C++:运算符重载:in-class 和 out-class。预增量运算符的歧义
C++: operator overloading: in-class and out-class. Ambiguity with preincrement operator
看看this code:
struct A
{
A operator+(A const& a) { cout << 1 << endl; return A(); }
A& operator++() { cout << 2 << endl; return *this; }
A operator++(int) { cout << 3 << endl; return *this; }
bool operator!() { cout << 4 << endl; return true; }
};
A operator+(A const& a, A const& b)
{ cout << 5 << endl; return A(); }
A& operator++(A& a) { cout << 6 << endl; return a; }
A operator++(A const& a, int) { cout << 7 << endl; return A(); }
bool operator!(A const& a) { cout << 8 << endl; return false; }
int main()
{
A a, b;
a + b; // Prints 1 instead 5
++a; // Ambiguity
a++; // Prints 3 instead 7
!a; // Prints 4 instead 8
return 0;
}
在每种情况下,都会选择运算符的 in-class 重载来对抗同一运算符的任何其他 out-class 重载,但预增量运算符不同:它会导致歧义在 in-class 和 out-class 过载之间。
为什么?
您的 post-increment 成员运算符不是 const
成员,而非成员是 const A&
参数。没有歧义,并且选择了非常量版本。这同样不适用于预增量版本。成员和非成员都绑定到非常量 A
,因此存在歧义。
看:
// non-const member. Does not require A operand to be const
A operator++(int)
// non-member. Requires A operand to be const
A operator++(A const& a, int)
看看this code:
struct A
{
A operator+(A const& a) { cout << 1 << endl; return A(); }
A& operator++() { cout << 2 << endl; return *this; }
A operator++(int) { cout << 3 << endl; return *this; }
bool operator!() { cout << 4 << endl; return true; }
};
A operator+(A const& a, A const& b)
{ cout << 5 << endl; return A(); }
A& operator++(A& a) { cout << 6 << endl; return a; }
A operator++(A const& a, int) { cout << 7 << endl; return A(); }
bool operator!(A const& a) { cout << 8 << endl; return false; }
int main()
{
A a, b;
a + b; // Prints 1 instead 5
++a; // Ambiguity
a++; // Prints 3 instead 7
!a; // Prints 4 instead 8
return 0;
}
在每种情况下,都会选择运算符的 in-class 重载来对抗同一运算符的任何其他 out-class 重载,但预增量运算符不同:它会导致歧义在 in-class 和 out-class 过载之间。
为什么?
您的 post-increment 成员运算符不是 const
成员,而非成员是 const A&
参数。没有歧义,并且选择了非常量版本。这同样不适用于预增量版本。成员和非成员都绑定到非常量 A
,因此存在歧义。
看:
// non-const member. Does not require A operand to be const
A operator++(int)
// non-member. Requires A operand to be const
A operator++(A const& a, int)