ClassType转换 - 运算符+不明确

时间:2011-03-20 01:08:36

标签: c++ type-conversion

在下文中,我希望将obj转换为int,但为什么它会在以下内容中返回operator + ambiguous?

class MyClass
{
public:
    MyClass(int X = 0, double Y = 0):x(X), y(Y){}

    operator int() const  { return x; }
    operator double() const  { return y; }

private:
    int x;
    double y;
};

int main()
{
    MyClass obj(10, 20);

    int x = obj + 5; //obj converted to int
}

3 个答案:

答案 0 :(得分:4)

因为两次转换都是等价的,所以它不明确。请记住,C ++语言直接为+double的参数定义int,不涉及标准转换。

所以这些功能都不比另一个好:

  • double operator+ (double, int) - 需要一次用户定义的转化,无需标准转化
  • int operator+ (int, int) - 需要一次用户定义的转化,无需标准转化

如果你想让它工作,你需要自己提供所有常用的算术运算符,而不是依赖隐式转换运算符。

  • double operator+ (const MyClass&, int) - 需要一次标准转换
  • int operator+ (const MyClass&, double) - 无需转换

现在obj + 5将有一个明确的最佳匹配。


C ++ 0x draft n3245在[over.built]

部分中说
  
      
  • 在本小节中,术语提升的整数类型用于表示由整体提升保留的那些整数类型(包括例如intlong,但不包括例如char)。类似地,术语提升的算术类型指的是浮动类型加上提升的整数类型。
  •   
     

对于每对提升的算术类型L和R,存在形式

的候选运算符函数
LR operator*(L,  R);
LR operator/(L,  R);
LR operator+(L,  R);
LR operator-(L,  R);
bool       operator<(L,  R);
bool       operator>(L,  R);
bool       operator<=(L,  R);
bool       operator>=(L,  R);
bool       operator==(L,  R);
bool       operator!=(L,  R);
     

其中LR是类型LR之间通常的算术转换的结果。

答案 1 :(得分:1)

您需要进行显式强制转换,以指示编译器您确实需要整数。

int x = static_cast<int>(obj) + 5; //obj converted to int

答案 2 :(得分:1)

当然,你可以通过重载+中的operator MyClass来解决这个问题(而不是Ben Voigt's answer中的全局问题):

int operator +(const int rhs) const
{
    return x + rhs;
}

int operator +(const double rhs) const
{
    return y + rhs;
}

整洁而明确。