【问题标题】:C++ conversion operator error?C++ 转换运算符错误?
【发布时间】:2012-09-30 21:59:47
【问题描述】:

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

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 转换运算符一起使用的所有转换时,代码可以正确编译。

【问题讨论】:

  • 为什么首先需要两个不同的加号运算符?这似乎是令人惊讶和困惑的秘诀。

标签: c++ operator-overloading operator-keyword


【解决方案1】:

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

来自C++ 编码标准

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

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

并非所有变化都是进步:隐式转换通常可以做更多事情 伤害总比好。在提供隐式转换之前三思而后行 并且从您定义的类型中,并且更喜欢依赖显式 转换(显式构造函数和命名转换函数)。

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

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

【讨论】:

    【解决方案2】:

    发生这种情况是因为转换运算符提供了从您的类到浮点数的隐式方法。因此,其他涉及浮点数的加法运算符会妨碍您。

    要解决这个问题,如果您真的希望转换成为可能,最好的解决方案是将其标记为显式:

    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-01-27
      • 2020-06-17
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多