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.