0

在类声明中重载的运算符:

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 个重载有类似的转换

   : 可能是 'Asdf Asdf::operator +(float)'

   :'Asdf Asdf::operator +(const Asdf &) const'

当我删除与重载float转换运算符一起使用的所有转换时,代码会正确编译。

4

2 回答 2

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();
于 2012-09-30T22:05:32.713 回答
3

隐式转换运算符往往会引起这类歧义,尤其是在与隐式构造函数结合使用时。

来自C++ 编码标准

  1. 考虑重载以避免隐式类型转换。

不要超出必要的对象相乘(奥卡姆剃刀):隐式类型转换提供了语法上的便利(但参见条款 40)。但是当创建临时对象的工作是不必要的并且优化是适当的(参见条款 8)时,您可以提供具有与常见参数类型完全匹配并且不会导致转换的签名的重载函数。

并非所有的改变都是进步:隐式转换往往弊大于利。在提供与您定义的类型之间的隐式转换之前要三思而后行,并且更喜欢依赖显式转换(显式构造函数和命名转换函数)。

其中很多都涉及到提供隐式转换可能导致的效率和意外行为,但是函数重载导致的歧义错误包含在提供隐式转换运算符和/或构造函数时很容易遇到的副作用中。

解决方案:让您的运营商明确或尽量避免提供它。这可能很方便,但它可能会引起像这样令人讨厌的惊喜(编译器错误实际上是最不讨厌的)。

于 2012-09-30T22:09:08.017 回答