Consider a C++20 program that uses an overloaded == operator, such as the following.
class A {
int value;
public:
A(int value) : value(value) {}
bool operator==(const A& other) {
return value == other.value;
}
};
int main() {
A a1(1);
A a2(2);
bool equal = a1 == a2;
return 0;
}
In ==
in main
, MSVC gives us this error:
error C2666: 'A::operator ==': overloaded functions have similar conversions
note: could be 'bool A::operator ==(const A &)'
note: or 'bool A::operator ==(const A &)' [synthesized expression 'y == x']
note: while trying to match the argument list '(A, A)'
Yes, the two alternatives that it tells us it “could be” are identical. What the heck?
Clang gives us an infinitely better error (especially the last line):
warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'A' and 'A') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
18 | bool equal = a1 == a2;
| ~~ ^ ~~
note: ambiguity is between a regular call to this operator and a call with the argument order reversed
10 | bool operator==(const A& other) {
| ^
note: mark 'operator==' as const or add a matching 'operator!=' to resolve the ambiguity
GCC does similar:
In function 'int main()':
warning: C++20 says that these are ambiguous, even though the second is reversed:
18 | bool equal = a1 == a2;
| ^~
note: candidate 1: 'bool A::operator==(const A&)'
10 | bool operator==(const A& other) {
| ^~~~~~~~
note: candidate 2: 'bool A::operator==(const A&)' (reversed)
note: try making the operator a 'const' member function
As is now clear, the real error is that we forgot to add the const
qualifier to operator==
. MSVC’s errors and Clang and GCC’s warnings go away when we remedy this.
bool operator==(const A& other) const {
return value == other.value;
}