A weird MSVC error (C2666)

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;
}

Posted

in

by

Tags: