diff --git a/source/basic.tex b/source/basic.tex index 1758d41fba..170f0a8428 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4089,10 +4089,9 @@ \pnum When an object of class type \tcode{X} is passed to or returned from a function, -if each copy constructor, move constructor, and destructor of \tcode{X} -is either trivial or deleted, -and \tcode{X} -has at least one non-deleted copy or move constructor, +if \tcode{X} has at least one eligible copy or move constructor\iref{special}, +each such constructor is trivial, +and the destructor of \tcode{X} is either trivial or deleted, implementations are permitted to create a temporary object to hold the function parameter or result object. @@ -4100,7 +4099,7 @@ from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by -using the non-deleted trivial constructor to copy the temporary +using the eligible trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object). diff --git a/source/classes.tex b/source/classes.tex index 82ef9e827d..443972d249 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -146,19 +146,19 @@ A \defnadj{trivially copyable}{class} is a class: \begin{itemize} -\item where each copy constructor, move constructor, copy assignment operator, -and move assignment operator~(\ref{class.copy.ctor}, \ref{class.copy.assign}) -is either deleted or trivial, -\item that has at least one non-deleted copy constructor, move constructor, -copy assignment operator, or move assignment operator, and +\item that has at least one eligible +copy constructor, move constructor, +copy assignment operator, or +move assignment operator~(\ref{special}, \ref{class.copy.ctor}, \ref{class.copy.assign}), +\item where each eligible copy constructor, move constructor, copy assignment operator, +and move assignment operator is trivial, and \item that has a trivial, non-deleted destructor\iref{class.dtor}. \end{itemize} \pnum A \defnadj{trivial}{class} is a class that is trivially copyable and -has one or more default constructors\iref{class.default.ctor}, -all of which are either trivial or deleted and -at least one of which is not deleted. +has one or more eligible default constructors\iref{class.default.ctor}, +all of which are trivial. \begin{note} In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.\end{note} @@ -1147,10 +1147,10 @@ \indextext{constructor!move}% \indextext{assignment operator!copy}% \indextext{assignment operator!move}% -The default constructor\iref{class.default.ctor}, -copy constructor, move constructor\iref{class.copy.ctor}, -copy assignment operator, move assignment operator\iref{class.copy.assign}, -and destructor\iref{class.dtor} are +Default constructors\iref{class.default.ctor}, +copy constructors, move constructors\iref{class.copy.ctor}, +copy assignment operators, move assignment operators\iref{class.copy.assign}, +and prospective destructors\iref{class.dtor} are \term{special member functions}. \begin{note} The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. @@ -1195,6 +1195,25 @@ ensures that only derived classes and friends can create objects using it. \end{example} +\pnum +Two special member functions are of the same kind if: +\begin{itemize} +\item they are both default constructors, +\item they are both copy or move constructors +with the same first parameter type, or +\item they are both copy or move assignment operators +with the same first parameter type +and the same \grammarterm{cv-qualifier}s and \grammarterm{ref-qualifier}, if any. +\end{itemize} + +\pnum +An \defnadj{eligible}{special member function} is a special member function for which: +\begin{itemize} +\item the function is not deleted, +\item the associated constraints\iref{temp.constr}, if any, are satisfied, and +\item no special member function of the same kind is more constrained\iref{temp.constr.order}. +\end{itemize} + \pnum For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract\iref{class.abstract}, its virtual base @@ -1205,8 +1224,8 @@ \indextext{special member function|see{constructor}}% \pnum -Constructors do not have names. -In a declaration of a constructor, the \grammarterm{declarator} is a +A \defn{constructor} is introduced by a declaration +whose \grammarterm{declarator} is a function declarator\iref{dcl.fct} of the form \begin{ncbnf} @@ -1231,7 +1250,7 @@ \grammarterm{id-expression} is a \grammarterm{qualified-id} that names a constructor\iref{class.qual}. \end{itemize} - +Constructors do not have names. In a constructor declaration, each \grammarterm{decl-specifier} in the optional \grammarterm{decl-specifier-seq} shall be \tcode{friend}, \tcode{inline}, \tcode{constexpr}, or an \grammarterm{explicit-specifier}. @@ -2093,7 +2112,8 @@ \indextext{special member function|see{destructor}}% \pnum -In a declaration of a destructor, the \grammarterm{declarator} is a +A \defnadj{prospective}{destructor} is introduced by a declaration +whose \grammarterm{declarator} is a function declarator\iref{dcl.fct} of the form \begin{ncbnf} @@ -2121,10 +2141,41 @@ same class as the \grammarterm{nested-name-specifier}. \end{itemize} -A destructor shall take no arguments\iref{dcl.fct}. +A prospective destructor shall take no arguments\iref{dcl.fct}. Each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} -of a destructor declaration (if any) shall be \tcode{friend}, \tcode{inline}, or -\tcode{virtual}. +of a prospective destructor declaration (if any) +shall be \tcode{friend}, \tcode{inline}, or \tcode{virtual}. + +\pnum +\indextext{generated destructor|see{destructor, default}}% +\indextext{destructor!default}% +If a class has no user-declared +prospective destructor, +a prospective destructor is implicitly +declared as defaulted\iref{dcl.fct.def}. +An implicitly-declared prospective destructor is an +inline public member of its class. + +\pnum +An implicitly-declared prospective destructor for a class \tcode{X} will have the form +\begin{codeblock} +~X() +\end{codeblock} + +\pnum +At the end of the definition of a class, +overload resolution is performed +among the prospective destructors declared in that class +with an empty argument list +to select the \defn{destructor} for the class, +also known as the \defnadj{selected}{destructor}. +The program is ill-formed if overload resolution fails. +Destructor selection does not constitute +a reference to, +or odr-use\iref{basic.def.odr} of, +the selected destructor, +and in particular, +the selected destructor may be deleted\iref{dcl.fct.def.delete}. \pnum \indextext{restriction!destructor}% @@ -2151,15 +2202,6 @@ has the same exception specification as if it had been implicitly declared\iref{except.spec}. \end{note} -\pnum -\indextext{generated destructor|see{destructor, default}}% -\indextext{destructor!default}% -If a class has no user-declared -destructor, a destructor is implicitly -declared as defaulted\iref{dcl.fct.def}. -An implicitly-declared destructor is an -inline public member of its class. - \pnum A defaulted destructor for a class \tcode{X} is defined as deleted if: @@ -2241,11 +2283,12 @@ \pnum \indextext{destructor!virtual}% \indextext{destructor!pure virtual}% -A destructor can be declared +A prospective destructor can be declared \tcode{virtual}\iref{class.virtual} or pure -\tcode{virtual}\iref{class.abstract}; -if any objects of that class or any derived class are created in the program, +\tcode{virtual}\iref{class.abstract}. +If the destructor of a class is virtual and +any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual. diff --git a/source/declarations.tex b/source/declarations.tex index 8a4dfa0066..2e62156ff3 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6067,6 +6067,12 @@ for them~(\ref{class.ctor}, \ref{class.dtor}, \ref{class.copy.ctor}, \ref{class.copy.assign}), which might mean defining them as deleted. +A defaulted prospective destructor\iref{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\iref{special} +is defined as deleted. A function is \defn{user-provided} if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function diff --git a/source/expressions.tex b/source/expressions.tex index fc579c8902..fda0f815ef 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3111,10 +3111,11 @@ After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer-to-member, or class type, the program is ill-formed. Passing a potentially-evaluated -argument of class type\iref{class} having a non-trivial -copy constructor, a non-trivial move constructor, +argument of class type\iref{class} having an eligible non-trivial +copy constructor, an eligible non-trivial move constructor, or a -non-trivial destructor, with no corresponding parameter, is conditionally-supported with +non-trivial destructor\iref{special}, +with no corresponding parameter, is conditionally-supported with \impldef{passing argument of class type through ellipsis} semantics. If the argument has integral or enumeration type that is subject to the integral promotions\iref{conv.prom}, or a floating-point type that is subject to the diff --git a/source/templates.tex b/source/templates.tex index 09f9469d30..ac60a8e1a4 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -6426,6 +6426,10 @@ and is an explicit instantiation definition of only those members that have been defined at the point of instantiation. +\pnum +An explicit instantiation of a prospective destructor\iref{class.dtor} +shall name the selected destructor of the class. + \pnum Except for inline functions and variables, declarations with types deduced from their initializer or return value\iref{dcl.spec.auto}, \tcode{const} variables of