3

Is it valid to delete copy or move assignment operators (maybe exclusively) using the following signature (note the void as result type)?

struct A
{
    A() = default;
    void operator = (const A &) = delete;
    void operator = (A &) = delete;
    void operator = (A &&) = delete;
};

G++/clang++ accepts above code (practically it may be considered as shortening). Are there more strict requirements for signatures of assignment operators to make them explicitly deleted?

Is there any interference in case of inheritance?

Barry
  • 286,269
  • 29
  • 621
  • 977
Tomilov Anatoliy
  • 15,657
  • 10
  • 64
  • 169
  • If you have a user-declared copy constructor the compiler will not create a default move constructor. Pretty sure the same applies to assignment. – user4581301 Apr 11 '18 at 17:58
  • These are the key 5 methods [Rule of 5](https://stackoverflow.com/questions/29465527/c-rule-of-5-copy-and-move-constructor-and-assignment-caveat-to-copy-or-move) – Gem Taylor Apr 11 '18 at 17:59
  • @user4581301 *maybe exclusively* here means, that any combination or even the only of mentioned operators may be present in actual implementation. – Tomilov Anatoliy Apr 11 '18 at 18:00
  • @GemTaylor Irrelevant here. The question is about signatures of operators, not about an idioms. – Tomilov Anatoliy Apr 11 '18 at 18:01
  • Interesting point. Diving into the standard. It should be covered in **[class.copy]**. Back if I find anything interesting. – user4581301 Apr 11 '18 at 18:02
  • 1
    [agh! Too slow] That link shows the correct signatures for the 4 copy operations you need to = delete if you want to disable copying. You can get away with not setting the return type, but it is not good practice, and at some point you may get a compiler warning. – Gem Taylor Apr 11 '18 at 18:06
  • Only hard requirement I'm seeing is [A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.](https://timsong-cpp.github.io/cppwp/n3337/class.copy#17). Absolutely nothing about the return type. – user4581301 Apr 11 '18 at 18:07

2 Answers2

2

It's perfectly valid. If your class does not need/want/cannot work with those functions then making that explicit and deleting them is the right thing to do (and even though return types don't participate in overload resolution you may want to get them correct just to reduce confusion).

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
2

From [class.copy.assign]:

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

and similarly for move:

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

There is no restriction here on the return type. Only on the parameter type. The version of these that the compiler generates returns X&, but that in no way obligates you to do the same thing.

If you're deleting the assignment operator anyway, returning void is fine. Note that you do not need to delete both the copy and move assignment operators. If you delete the copy assignment, the move won't be implicitly generated.

Is there any interference in case of inheritance?

No. The implicitly generated assignment operators would just be defined as deleted (and would return X&, although that's orthogonal). If you declare one, then that's of course up to you to do whatever you want.

Barry
  • 286,269
  • 29
  • 621
  • 977