Jason Merrill
WG21 P2706R0
2022-11-08

US 26-061: Redundant specification for defaulted functions

Problem Statement

The rule about the implicit definition of an explicitly-defaulted function is redundant with the rule in [dcl.fct.def.default]/5.

NB Suggested Resolution

Restrict this paragraph to implicitly declared members.

Proposed Resolution

Change [dcl.fct.def.default]/5:
Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor], [class.dtor], [class.copy.ctor], [class.copy.assign]) as described below, including possibly defining them as deleted. A defaulted prospective destructor ([class.dtor]) that is not a destructor is defined as deleted. A defaulted special member function that is neither a prospective destructor nor an eligible special member function ([special]) is defined 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 implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. A non-user-provided defaulted function (i.e. implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) or needed for constant evaluation ([expr.const]).
Change [special]/1:
[Note 1: The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. The implementation will implicitly define them as needed ([dcl.fct.def.default]). if they are odr-used ([basic.def.odr]) or needed for constant evaluation ([expr.const]). — end note]
Change [class.default.ctor]/4:
A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to initialize an object of its class type ([intro.object]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. The An implicitly-defined ([dcl.fct.def.default]) default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer ([class.base.init]) and an empty compound-statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr function ([dcl.constexpr]), the implicitly-defined default constructor is constexpr. Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members are implicitly defined.
Change [class.copy.ctor]/12:
A copy/move constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration.
[Note 5: The copy/move constructor is implicitly defined even if the implementation elided its odr-use ([basic.def.odr], [class.temporary]). — end note]
If the an implicitly-defined ([dcl.fct.def.default]) constructor would satisfy the requirements of a constexpr function ([dcl.constexpr]), the implicitly-defined constructor is constexpr.
Change [class.copy.assign]/10:
A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) (e.g., when it is selected by overload resolution to assign to an object of its class type), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. The An implicitly-defined ([dcl.fct.def.default]) copy/move assignment operator is constexpr.
Remove [class.dtor]/10:
A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) or when it is explicitly defaulted after its first declaration.
Change [class.compare.default]/1:
A comparison operator function for class C that is defaulted on its first declaration and is not defined as deleted is implicitly defined when it is odr-used or needed for constant evaluation. Name lookups in the defaulted implicit definition ([dcl.fct.def.default]) of a comparison operator function are performed from a context equivalent to its function-body. A definition of a comparison operator as defaulted that appears in a class shall be the first declaration of that function.