A class with a reference member has no default-provided copy/move assignment operators. References cannot be rebound to reference a different variable once binding is established. In short, the copy constructor is making that initial establishment, while the default assignment operator would be trying to change it after-binding.
The standard therefore calls this case out for both default copy and move assignment operators.
C++11 § 12.8p23
A defaulted copy/move assignment operator for class X is defined as deleted if X has:
- a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- a non-static data member of const non-class type (or array thereof), or
- a non-static data member of reference type, or
- a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M’s corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator, or
- a direct or virtual base class B that cannot be copied/moved because overload resolution (13.3), as applied to B’s corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator, or
- for the move assignment operator, a non-static data member or direct base class with a type that does not have a move assignment operator and is not trivially copyable, or any direct or indirect virtual base class.
You can certainly write your own overload.
#include <iostream>
struct A
{
A(int& var) : r(var) {}
int &r;
A& operator=(const A& obj)
{
r = obj.r; // value copied, reference-binding remains the same
return *this;
}
};
int main(int argc, char** argv)
{
int x = 42;
int y = 43;
A a1(x);
A a2(y);
A a3 = a1; // legal. default copy-ctor invoked
a3 = a2; // legal. user-defined copy-assignment invoked
std::cout << x << ',' << y << '\n';
return 0;
}
Output
43,43
But this will not (and cannot) rebind the reference. The overload provided here changes the referenced data; not the references themselves. Such a distinction is important.
Hope this helps.