This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


2477. Defaulted vs deleted copy constructors/assignment operators

Section: 11.4.5.3  [class.copy.ctor]     Status: CD6     Submitter: Andrew Rogers     Date: 2021-02-04

[Accepted as a DR at the June, 2021 meeting.]

According to 11.4.5.3 [class.copy.ctor] paragraph 6,

If the class definition does not explicitly declare a copy constructor, a non-explicit 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 (9.5 [dcl.fct.def]).

However, this rule is contradicted by paragraph 10, which lists a number of other reasons why a defaulted copy constructor will be defined as deleted, rather than being “defined as defaulted,” as required by paragraph 6:

A defaulted copy/move constructor for a class X is defined as deleted (9.5.3 [dcl.fct.def.delete]) if X has:

A similar contradiction exists for copy assignment operators in 11.4.6 [class.copy.assign] paragraphs 2 and 7.

Proposed resolution (April, 2021):

  1. Change 11.4.5.3 [class.copy.ctor] paragraph 6 as follows:

  2. If the class definition does not explicitly declare a copy constructor, a non-explicit 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 (9.5 [dcl.fct.def]). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor (D.7 [depr.impldec]).
  3. Change 11.4.6 [class.copy.assign] paragraph 2 as follows:

  4. 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 (9.5 [dcl.fct.def]). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor (D.9). The implicitly-declared...