(否)在调用重载运算符时键入类型转换

时间:2017-11-20 21:32:15

标签: 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);
}

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*);

1 个答案:

答案 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.