在类声明中重载的运算符:
class Asdf{
operator float() const;
Asdf operator+(const Asdf&) const;
Asdf operator+(float);
}
int main()
{
Asdf object1, object2, object3;
//Receiving error: "more than one operator '+' matches these operands"
object1= object2 + object3;
_getch();
return 0;
}
错误:
:error C2666: 'Asdf::operator +' : 3 overloads have similar conversions :could be 'Asdf Asdf::operator +(float)' :'Asdf Asdf::operator +(const Asdf &) const'
当我删除与重载float
转化运算符一起使用的所有转化时,代码会正确编译。
答案 0 :(得分:3)
这种情况正在发生,因为转换运算符提供了从类到浮点的隐式方法。因此,涉及花车的其他附加操作员会妨碍。
要解决此问题,如果您真的希望转换成为可能,那么最佳解决方案是将其标记为显式:
explicit operator float() const;
Asdf a;
float f = static_cast<float>(a);
但是,这仅适用于C ++ 11。在C ++ 03中,更好的选择是使用函数:
float toFloat() const;
Asdf a;
float f = a.toFloat();
答案 1 :(得分:3)
隐式转换运算符往往会引发这些歧义,尤其是在与隐式构造函数结合使用时。
来自 C ++编码标准:
- 考虑重载以避免隐式类型转换。
醇>不要超越必要的物体(Occam's Razor):隐含 类型转换提供了语法上的便利(但参见条款40)。但 当创建临时对象的工作是不必要的时候 优化是合适的(见第8项),您可以提供重载 具有完全匹配常见参数类型的签名的函数 不会导致转换。
并非所有变化都是进步:隐式转化通常可以做得更多 伤害比好。在提供隐式转换之前请三思而后行 从您定义的类型,并更喜欢依赖显式 转换(显式构造函数和命名转换函数)。
其中很多都涉及提供隐式转换可能导致的效率和意外行为,但是在提供隐式转换运算符和/或构造函数时,您可以轻松遇到的副作用中包含函数重载的歧义错误。 / p>
解决方案:让您的运营商明确或尽量避免提供。它可能很方便,但它可以引起这样令人讨厌的惊喜(编译器错误实际上是最不讨厌的)。