何时使用转换操作符

When to use conversion operators?

本文关键字:操作符 转换 何时使      更新时间:2023-10-16

考虑下面的例子,int a = objT + 5;行给出了模糊的转换,它以两种方式处理,使用我认为不应该必要的显式强制转换,并用成员函数代替转换操作符的使用。在这里,我的问题是,你应该继续使用转换操作符还是根本不使用?

class Testable {
public:
    Testable(int val = 0):x(val){}
    operator int() const  { return x; }
    operator double() const  { return x; }
    int toInt() { return x; }
    double toDouble() { return x; }
private:
    int x;
};
int main()
{
    Testable objT(10);
    // ambiguous conversion
    int a = objT + 5;
    // why to use explicit cast when
    // the conversion operator is for to handle
    // this automatically
    int b = static_cast<int>(objT) + 5;
    // member functions
    int c = objT.toInt() + 5;
}

注意int d = objT;double e = objT;都是明确的,这里编译器可以明确地选择转换操作符,因为左边的类型和这些转换操作符的返回类型是精确匹配的。

来自objT + 5的模糊转换结果(同样注意:long f = objT;也是模糊的)。问题是,您已经拿走了编译器需要的基本信息,而这些信息是用来无意识地执行消歧的。

如果去掉这两个转换操作符中的任何一个,问题就会消失。由于底层数据成员是int,我建议去掉operator double()

对于您的特殊情况,您可以只提供到double的转换,因为它具有到int的标准转换。然而,隐性转换往往弊大于利。如果您使用它们,那么避免从int(您的非显式构造函数)转换到int,我认为这是您当前问题的根源。

这个问题和我的问题类似,是否有可能改变隐式转换操作符的优先级。遗憾的是,没有令人满意的解决方案,隐式转换之间没有优先级。

一种解决方案是对有歧义的函数或操作符进行额外的重载,在这种情况下,它们是operator + (const Testable& int)和operator + (const Testable&, double)。

另一个解决方案是简单地只留下一个隐式转换,在您的情况下,整数转换是最好的。

仅在迫切需要自动转换到给定类型时使用隐式转换。显式的toInt、toDouble函数要好得多,它们使代码更加清晰,并且不会隐藏潜在的缺陷。对一元构造函数使用explicit关键字,它们会阻止通过该构造函数的隐式转换。

不,不可能链接隐式转换,无论是操作符还是构造函数。c++标准规定在一个转换序列中只能有一个隐式转换

不需要隐式转换为double。您总是返回十进制值,编译器可以组合多个隐式转换操作符。

如果int类型的私有属性x是double类型,我建议不要使用隐式转换为int,因为这会导致精度损失。