考虑到以下示例,行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;
}
答案 0 :(得分:2)
请注意int d = objT;
是明确的,double e = objT;
这里编译器可以明确地选择转换运算符,因为左侧的类型与这些转换运算符的返回类型完全匹配
来自objT + 5
的模糊转换结果(另请注意:long f = objT;
也不明确)。问题在于你已经删除了编译器无意识地执行消歧的基本信息。
如果你摆脱这些转换运算符中的任何一个,问题就会消失。由于基础数据成员是int
,我建议删除operator double()
。
答案 1 :(得分:0)
对于您的特定情况,您可以将转换提供为double,因为它具有到int的标准转换。但是,隐式转换通常比帮助更有害。如果你使用它们,那么避免同时从int(你的非显式构造函数)和int转换,我认为这是你当前问题的根源。
答案 2 :(得分:0)
您不需要隐式转换为double。您始终返回十进制值,编译器可以组合多个隐式转换运算符。
如果int类型的私有属性x是double,我建议不要使用隐式转换为int,因为它会导致精度损失。
答案 3 :(得分:0)
这个问题与我的问题相似,whether is it possible to change the precedence of implicit conversion operators。遗憾的是,没有令人满意的解决方案,隐式转换中没有优先权。
一种解决方案是对模糊函数或运算符进行额外的重载,在这种情况下,它们是operator +(const Testable&amp;,int)和operator +(const Testable&amp;,double)。
另一个解决方案是简单地只留下一个隐式转换,在你的情况下,整数一个是最好的。
当您迫切需要自动转换为给定类型时,仅使用隐式转换。明确toInt,toDouble函数更好,他们澄清代码,不隐藏潜在的陷阱。对一元构造函数使用explicit关键字,它们通过该构造函数阻止隐式转换。
不,如果它们是运算符或构造函数,则无法链接隐式转换。 C ++标准要求只有1个隐式转换可以在转换序列中。