我想知道是否有一个选项可以在初始化/比较对象到特定类型的变量时禁用(?)类型转换:
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
}
这是错误:more than one operator "<=" matches these operands
有没有办法摆脱这些错误?
我知道我可以投放main
,但不幸的是,这不是我想要的,或者事实上甚至允许这样做:
X x3 = (long long)0; //no no no...
另外 - 没有std::string
。
回答(部分)
因此,可以通过更改类声明来解决赋值部分 - 摆脱long 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*);
答案 0 :(得分:1)
根据14882:2011 ISO C ++标准中13.3.3.1.1 [over.ics.scs]下的表12,调用不明确的原因是两个重载具有相同的标准转换等级。 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
};
您的部分解决方案&#34;工作&#34;,尽管您示例中的main()
中的第二行将不再编译。由于const char*
的转换是明确的,因此您不再允许这样做:
X x = "Hi there!"; // error: no implicit conversion from const char[10] to X
X x("Hi there!"); // ok
另一个警告是,使用long long
的操作可能会很昂贵,具体取决于您的X实现,因为在执行赋值/比较/等之前需要先构造临时X.