6

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?

1 Answer 1

10

Clang is correct, the others aren't.

Both of your declared assignment operators are copy assignment operators per [class.copy.assign]/1:

A user-declared copy assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one non-object parameter of type X, X&, const X&, volatile X&, or const volatile X&.

In both of your operator= declarations the first parameter is the explicit object parameter (because of this), i.e. an object parameter, and therefore doesn't count in the determination for copy assignment operator.

As a consequence, the compiler must not declare any copy or move assignment operator implicitly.

There is no implicit overload that could be chosen in overload resolution.

See CWG 2586.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.