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
}
另外-no
std::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