Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to forbid assignment

Tags:

c++

c++11

Is there a reason to use the “canonical” signatures for operator=

class X {
  X& operator=(const X&) = delete;
  X& operator=(X&&) = delete;
};

instead of just

class X {
  void operator=(X) = delete;
};

when all you want to do is delete it?

Upd:
Also, consider a situation when X has an explicitly declared move or copy constructor.

class X {
public:
  X(X&&);
};

In that case op=(X&&) and op=(const X&) are implicitly deleted, but I want to explicitly express that assignment is not allowed.

like image 731
Abyx Avatar asked Dec 09 '15 18:12

Abyx


1 Answers

No, there is no technical reason to use the canonical copy assignment operator signature.

As seen in the standard, [dcl.fct.def.delete] §8.4.3:

  1. A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed. [ Note: This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function. It applies even for references in expressions that are not potentially-evaluated. If a function is overloaded, it is referenced only if the function is selected by overload resolution. — end note ]

Therefore a deleted function's name, in this case operator=, may only be used if the compiler finds a preferable overload resolution. However, such an overload cannot exist, as X and const X& are indistinguishable as parameters ([over.ics.rank] §13.3.3.2) and the return value is ignored.

That being said, there is a stylistic reason to use the canonical signature. The mere fact that this question exists shows that anyone reading your code may not know the meaning and assume it is doing something special. For readability's sake, I would recommend you use the familiar X& operator=(const X&) = delete;.

like image 183
nwn Avatar answered Sep 27 '22 20:09

nwn