C++11 (否)调用重载运算符时进行类型转换
我想知道在初始化/比较对象与特定类型变量时是否有禁用(?)类型转换的选项:C++11 (否)调用重载运算符时进行类型转换,c++11,casting,operator-overloading,c-strings,C++11,Casting,Operator Overloading,C Strings,我想知道在初始化/比较对象与特定类型变量时是否有禁用(?)类型转换的选项: class X { //... const bool operator<=(const long long val) const; const bool operator<=(const char* val) const; const X& operator=(const long long val); const X& operator=(const char* val)
class X {
//...
const bool operator<=(const long long val) const;
const bool operator<=(const char* val) const;
const X& operator=(const long long val);
const X& operator=(const char* val);
}
int main() {
X x1 = 10; //thats ok
X x2 = "123"; //ok again
X x3 = 0; //error, 0 is 'valid' char*
x1 <= 0 ? true : false; //error, same reason
}
另外-nostd::string
回答(部分) 因此,赋值部分可以通过改变类声明来解决——去掉
long
赋值,并使适当的构造函数显式/隐式
// allow implicit conversion from long long, ex. X x = 13;
X(long long val)
// disable implicit conversion from const char*, now X x = 0 is ok - calls the above
explicit X(const char* val);
// allow assignment from const char as well, no confusion with 0 now
const X& operator=(const char*);
< P>调用的原因是两个重载都具有相同的标准转换等级,根据表12中的133.3.1.1 [Obj.ICS.SC]在1488年至2011年的ISO C++标准中。
0
文本的类型为int
。到long-long
的转换是积分转换(见4.7),到const-char*
的转换是指针转换(见4.10)
最简单的解决方案是只为int
添加重载。您只需将参数强制转换为long long
,即可调用相应构造函数/运算符的long long
版本,如下所示:
class X
{
public:
// ...
X(int i) : X((long long)i) { }
const X& operator=(int i) { return operator=((long long)i); }
// etc
};
虽然示例中main()
中的第二行不再编译,但部分解决方案“有效”。由于从const char*
的转换是显式的,因此不再允许您执行此操作:
X x = "Hi there!"; // error: no implicit conversion from const char[10] to X
X x("Hi there!"); // ok
另一个警告是,使用
long
的操作可能会非常昂贵,这取决于X的实现,因为在执行赋值/比较等操作之前,需要先构造一个临时X。如果您可以去掉赋值运算符并用替换它们,那么您将消除错误。不过,不可能有明确的作业。谢谢@RainingChain,@a-a我按照你的建议运行了作业,但仍然添加了一个重载,取int
0
更喜欢它而不是char*
。后缀是选项吗?例如xx3=0ll代码>
X x = "Hi there!"; // error: no implicit conversion from const char[10] to X
X x("Hi there!"); // ok