Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does deleting a copy constructor or copy assignment operator count as "user declared"?

Per this presentation, if either the copy constructor or copy assignment operator is "user declared", then no implicit move operations will be generated. Does deleteing the copy constructor or copy assignment operator count as "user declared"?

struct NoCopy {
    NoCopy(NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
};

Will implicit move operations be generated for the NoCopy class? Or does deleting the relevant copy operations count as "user declared" and thus inhibit implicit move generation?

If possible, I'd prefer an answer referencing the relevant parts of the standard.

like image 985
acm Avatar asked Mar 10 '15 12:03

acm


2 Answers

According to slide 14 of your presentation, a deleted copy constructor is "user declared" thus inhibiting the move generation.

like image 86
LawfulEvil Avatar answered Oct 22 '22 18:10

LawfulEvil


The term "user declared" doesn't have a formal definition in the standard. It is meant to be the opposite of "implicitly declared" in the context of special member functions. [dcl.fct.def.default]/4 could be a bit clearer about this fact, but the intention is there:

Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them (12.1 12.4, 12.8), which might mean defining them as deleted. A special member function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.

Both NoCopy(NoCopy&) = delete; and NoCopy& operator=(const NoCopy&) = delete; are declarations of special member functions. Since you are explicitly declaring them, as opposed to allowing the compiler to declare them implicitly, they are user-declared. Those declarations will therefore suppress the implicit declarations of the move constructor and move assignment operator per [class.copy]/9:

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

X does not have a user-declared copy constructor,

X does not have a user-declared copy assignment operator,

X does not have a user-declared move assignment operator,

X does not have a user-declared destructor, and

— the move constructor would not be implicitly defined as deleted.

like image 33
Casey Avatar answered Oct 22 '22 16:10

Casey