So if I've got a class and declare a copy assignment operator in it, obviously I want some special behavior when copying. I would expect the language to try to help me out by implicitly deleting the copy constructor until I explicitly bring it back, so as to avoid unintended different behavior when doing type instance = type()
as opposed to already_existing_instance = type()
.
It's recommended anyway that you explicitly declare both copy constructor and copy assignment operator when trying to declare one of them, precisely because C doesn't delete the other and causes you a headache.
An example of where I find this annoying is when deleting the copy assignment operator. If I want to quickly make a class non-copyable, I would expect deleting the copy assignment operator does the trick, but I have to explicitly delete the copy constructor as well.
My question is why does the compiler do this? Who thought this was a good idea? All it does is create a needless obstacle for the programmer or am I missing something?
P.S. This behavior doesn't present itself when doing the same thing with move constructors/assignment operators, why make a distinction between copy and move in this case?
CodePudding user response:
Them not being deleted is deprecated.
E.g. Clang 15 with -Wextra
, given
struct A
{
A() {}
A(const A &) {}
};
int main()
{
A a, b;
a = b;
}
spits
<source>:4:5: warning: definition of implicit copy assignment operator for 'A' is deprecated because it has a user-provided copy constructor [-Wdeprecated-copy-with-user-provided-copy]
A(const A &) {}
^
<source>:10:7: note: in implicit copy assignment operator for 'A' first required here
a = b;
^
Similarly,
struct A
{
A() {}
A &operator=(const A &) {return *this;}
};
int main()
{
A a, b(a);
}
gives
<source>:4:8: warning: definition of implicit copy constructor for 'A' is deprecated because it has a user-provided copy assignment operator [-Wdeprecated-copy-with-user-provided-copy]
A &operator=(const A &) {return *this;}
^
<source>:9:10: note: in implicit copy constructor for 'A' first required here
A a, b(a);
^