在下文中,我希望将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
}
答案 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]
- 在本小节中,术语提升的整数类型用于表示由整体提升保留的那些整数类型(包括例如
int
和long
,但不包括例如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
是类型L
和R
之间通常的算术转换的结果。
答案 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;
}
整洁而明确。