9
votes

The question is as my title states.

I'm asking because I have a class with a defaulted move constructor but code trying to perform copy assignment is failing stating that the copy assignment operator is deleted (according to Visual Studio 2015).

So I checked the rules here for implicitly declared copy assignment operators:

The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true:

  • ...
  • T has a user-declared move constructor
  • T has a user-declared move assignment operator

So basically I'm not sure if a defaulted move constructor counts as user-declared. My gut tells me yes but when it comes to standardese I always like to be sure since assumptions can be costly.

2
Yes​​​​​​​​​​​​​​​​​​​ - Praetorian
@Praetorian Fair enough. Why does VS2015 complain? When I remove my defaulted move constructor, code compiles fine. - void.pointer
Presumably your class contains data members that are all copy assignable. When you remove the user-declared move constructor there is nothing preventing implicit declaration of a copy assignment operator - Praetorian
@0x499602D2 you probably need 51540 rep .... - Fantastic Mr Fox

2 Answers

4
votes

The standard says:

12.8 Copying and moving class objects [class.copy]

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.

Your class has defaulted move constructor, but it is explicitly declared. So according to standard implicitly declared copy constructor and copy assignment operator is defined as deleted.

8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]

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 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.

Using this terminology your move constructor is user-declared, but not user-provided.

0
votes

A defaulted special member function is user-declared but it is also defined by the user as defaulted. The standard doesn't explicitly define the term "user-declared" but it essentially means any special member function that has to be written out by the user. So the following declares a constructor and defines it as defaulted.

struct X { 
    X() = default; // declaration and definition
};

Defining a member function as defaulted means the definition is equivalent to the implicit definition. It is user-declared by virtue of the fact that it had to be typed out by the user.