C++ C++;将自定义类型的转换运算符重载为std::string
我希望有人能够回答为什么下面的方法不起作用。但请容忍我,我仍然是一个非常愚蠢的人。。。 我就是搞不清楚为什么会发生下面的事情C++ C++;将自定义类型的转换运算符重载为std::string,c++,overloading,operator-keyword,C++,Overloading,Operator Keyword,我希望有人能够回答为什么下面的方法不起作用。但请容忍我,我仍然是一个非常愚蠢的人。。。 我就是搞不清楚为什么会发生下面的事情 using namespace std; #include <string> #include <iostream> class testClass { public: operator char* () {return (char*)"hi";}; operator int () {return 77;}; operator std::
using namespace std;
#include <string>
#include <iostream>
class testClass
{
public:
operator char* () {return (char*)"hi";};
operator int () {return 77;};
operator std::string () {return "hello";};
};
int main()
{
char* c;
int i;
std::string s = "goodday";
testClass t;
c = t;
i = t;
s = t;
cout<< "char: " << c << " int: " << i << " string: "<<s<<endl;
return 0;
}
它确实有效
我已经试了几个小时来理解这个错误消息,但最让我困惑的是它对char*有效
我很感激你的任何暗示。
谢谢
Markus事实上,这是因为
std::string
提供了一个赋值运算符,它接受const char*
错误试图解释的是,如果t
也是std::string
,那么您的赋值“s=t
”,其中s
是std::string
,将是有效的,或者如果t
是[const
]char*
。您的转换运算符可以将t
转换为其中任何一个,因此编译器没有选择其中一个的依据
您可以通过选择所需的转换来明确消除歧义:
s = t.operator std::string();
s = static_cast<std::string>(t);
s=t.operator std::string();
s=静态铸件(t);
或者,您可以只提供其中一个转换,并在必要时让用户进行进一步的转换
不过,最终你可能会发现,任何转换运算符都比它的价值更麻烦。。。它告诉我们,
std::string
本身并没有提供到const char*
的转换运算符,没有确切的std::string::operator=。这些候选人的意思是
s = (const std::string)(std::string)t;
s = (const char*)t;
s = (char)(int)t;
我认为如果您将其更改为返回const std::string,事情就会成功。(EDIT:我错了。)还要注意,第一个函数应该返回const char*。如果需要将字符串文字强制转换为char*,则说明您做错了什么;字符串文字不可写
$13.3.1.5/2表示“转换
S的函数及其基类
是被考虑的。那些不是
隐藏在S和屈服类型T或a中
可以转换为T类型的类型
通过标准转换序列
(13.3.3.1.1)是候选功能。
返回
cv合格类型被视为
生成的cv不合格版本
这种类型适用于此过程
选择候选函数。
返回的转换函数
“引用cv2 X”返回
类型“cv2 X”,因此
认为该工艺的产量为X
选择候选函数的方法。”
赋值s=t的工作原理如下:
a) 将考虑类型为“t”(testClass)的所有成员,这些成员可以将“t”转换为“s”
Candidate 1: operator string(); // s created using member string::operator=(string const&)
Candidate 2: operator char *() // s created using member string::operator=(char const*)
Candidate 3: operator char *() // s created using member string::operator=(char *)
b) 上述所有候选函数都是可行的(即,在没有其他候选函数的情况下,编译器可以成功地解析对其中任何一个函数的函数调用)
c) 然而,现在必须确定最佳可行的候选人。涉及的转换顺序包括:
Candidate 1: U1 : operator string()
Candidate 2: U2 : operator char*()->const qualification to match string::operator=(char const*)
Candidate 3: U3 : operator char*()
$13.3.3.1.1/3表示“a
转换顺序由
考虑到每个
序列中的转换和
任何引用绑定的秩
(13.3.3.1.4).如果其中任何一个
转换秩,序列具有
转换职级;”
这意味着U1、U2和U3都具有转换秩,并且在第一级,它们都不比另一个好。然而,该标准也规定
用户定义的转换序列U1为
更好的转换序列比
另一个用户定义的转换
序列U2,如果它们包含相同的
用户定义的转换函数或
构造函数,如果是第二个标准
U1的转换顺序较好
比第二个标准转换
U2的序列
那么,让我们看看这意味着什么
在U1和U2之间,它们涉及不同的转换函数,因此没有一个比另一个更好
在U1和U3之间,它们涉及不同的转换函数,因此没有一个比另一个更好
那么U1和U2呢。它们涉及相同的转换函数,满足上述“和”条件的第一部分
那么关于“如果U1的第二个标准转换序列比U2的第二个标准转换序列好”部分呢
在U2中,第二个标准转换序列需要常数限定,而在U3中则不需要常数限定。U3的第二个标准转换序列是完全匹配的
但正如标准中的表9所示,CV资格也被认为是完全匹配的
因此,就过载分辨率而言,U2和U3也确实难以区分
这意味着U1、U2和U3实际上都一样好,编译器发现解析调用(作为赋值语句的一部分)是不明确的,因为没有明确的最佳可行函数好吧,非常感谢大家。我想我已经开始掌握窍门了,有点 首先,我不知道这个事实,char只是一个8位int。谢谢你的澄清 所以我理解这一点,因为有三个赋值运算符是为std::string定义的,每个运算符在表达式的右侧都有不同的参数(string,char*,const char*)
s=t
不知道必须转换为哪种类型,因为有多个潜在的匹配(对于std::string的赋值)转换是用
operator int () {return 77;};
operator std::string () {return "hello";};
(自字符:8bit int)
或
是这样吗?所以用白痴的话来说,作业的左边没有告诉右边它期望的是哪种类型,所以rhs必须从它的选项中进行选择,其中一个和另一个一样好?std::string operator=是否容忍我的意图
到目前为止还不错,我想我明白了——但是,为什么下面的内容也会产生歧义呢
using namespace std;
#include <string>
#include <iostream>
class testClass
{
public:
operator float () {return float(77.333);};
operator std::string () {return "hello";};
};
int main()
{
std::string s = "goodday";
testClass t;
s = t;
cout<< " string: "<<s <<endl;
return 0;
}
使用名称空间std;
#包括
#包括
类testClass
{
公众:
运算符浮点(){返回浮点(77.333);};
运算符std::string(){返回“hello”;};
operator int () {return 77;};
operator std::string () {return "hello";};
operator char* () {return (char*)"hi";};
operator std::string () {return "hello";};
using namespace std;
#include <string>
#include <iostream>
class testClass
{
public:
operator float () {return float(77.333);};
operator std::string () {return "hello";};
};
int main()
{
std::string s = "goodday";
testClass t;
s = t;
cout<< " string: "<<s <<endl;
return 0;
}