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.