In addition to an implicitly-defined copy assignment operator, if a class also defines an operator= without an lvalue-reference object parameter, which of the operators must be selected?
Please consider the following example containing two structs, each with an overloaded copy assignment operator:
struct A {
int operator =(this const A &, const A&) { return 1; }
operator int() const { return 2; }
};
struct B {
int operator =(this volatile B &, const B&) { return 1; }
operator int() const { return 2; }
};
template<typename T>
int f(T t) {
return t = T{};
}
int main() {
return 10 * f(A{}) + f(B{});
}
The program returns two digits. The first digit is 1 if the user-defined operator = is selected in A a; a = A{}; and it is 2 if the implicitly-defined copy assignment operator is selected. The second digit similarly shows the selection, but for B b; b = B{}; current compilers disagree on the program's returned value.
Clang returns 11, meaning that both user-defined operators are preferred over implicitly-defined copy assignment operators.
MSVC returns 22, always selecting the implicitly-defined copy assignment operators over user-defined operators.
And GCC is in the middle, with the return value 21. Online demo: https://gcc.godbolt.org/z/d4hbe7cn8
Which compiler is correct here?