Home > other >  Why does declaring a copy constructor not delete the copy assignment operator and vice versa?
Why does declaring a copy constructor not delete the copy assignment operator and vice versa?

Time:11-22

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);
         ^
  • Related