According to the C++ reference on Copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true
T has a non-static data member of non-class type (or array thereof) that is const ...
I was hoping to create a case where I had a const class-type data member and a defaulted copy assignment operator not defined as deleted. In doing so, I found a discrepancy between clang and gcc. Consider the following code:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
When I compile this with g++ -std=c++14
I get the following errors:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, can’t use default assignment operator
note: synthesized method ‘A& A::operator=(const A&)’ first required here
This does, comma, however, compile with clang
, as the reference seems to indicate that it should. Am I in error? Which compiler is correct?
I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
and clang version 6.0.0-1ubuntu2
.
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc and as it was pointed out, the two rules relevant to this case don't apply
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.