diff --git a/source/classes.tex b/source/classes.tex index a610a4322c..485127a265 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -6588,35 +6588,39 @@ \end{example} \pnum +An \defnadj{implicitly movable}{entity} is +a variable of automatic storage duration +that is either a non-volatile object or +an rvalue reference to a non-volatile object type. In the following copy-initialization contexts, a move operation might be used instead of a copy operation: \begin{itemize} \item If the \grammarterm{expression} in a \tcode{return} or \tcode{co_return} statement\iref{stmt.return} is a (possibly parenthesized) \grammarterm{id-expression} -that names an object with automatic storage duration declared in the body +that names an implicitly movable entity declared in the body or \grammarterm{parameter-declaration-clause} of the innermost enclosing function or \grammarterm{lambda-expression}, or \item if the operand of a \grammarterm{throw-expression}\iref{expr.throw} -is the name of a non-volatile automatic object -(other than a function or catch-clause parameter) -whose scope does not extend beyond the end of the innermost enclosing -\grammarterm{try-block} (if there is one), +is a (possibly parenthesized) \grammarterm{id-expression} +that names an implicitly movable entity +whose scope does not extend beyond the \grammarterm{compound-statement} +of the innermost \grammarterm{try-block} or \grammarterm{function-try-block} +(if any) +whose \grammarterm{compound-statement} or \grammarterm{ctor-initializer} +encloses the \grammarterm{throw-expression}, \end{itemize} overload resolution to select the constructor for the copy or the \tcode{return_value} overload to call -is first performed as if the object were designated by an -rvalue. +is first performed as if the expression or operand were an rvalue. If the first overload resolution fails or was not performed, -or if the type of the first parameter of the selected -constructor or the \tcode{return_value} overload -is not an rvalue reference to the object's type (possibly cv-qualified), -overload resolution is performed again, considering the object as an lvalue. +overload resolution is performed again, +considering the expression or operand as an lvalue. \begin{note} This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor or the \tcode{return_value} overload to be called if elision is not performed, and the selected constructor -or the \tcode{return_value} overload must be accessible even if +or \tcode{return_value} overload must be accessible even if the call is elided. \end{note} @@ -6653,6 +6657,28 @@ \end{codeblock} \end{example} +\pnum +\begin{example} +\begin{codeblock} +void f() { + T x; + try { + T y; + try { g(x); } + catch (...) { + if (/*...*/) + throw x; // does not move + throw y; // moves + } + g(y); + } catch(...) { + g(x); + // g(y); // error + } +} +\end{codeblock} +\end{example} + \rSec1[class.compare]{Comparisons}% \rSec2[class.compare.default]{Defaulted comparison operator functions}% diff --git a/source/compatibility.tex b/source/compatibility.tex index a6c50406ab..ad3a32f1af 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -2035,6 +2035,35 @@ }; \end{codeblock} +\diffref{class.copy.elision} +\change +A function returning an implicitly movable entity\iref{class.copy.elision} +may invoke a constructor taking an rvalue reference to a type +different from that of the returned expression. +Function and catch-clause parameters can be thrown using move constructors. +\rationale +Side effect of making it easier to write +more efficient code that takes advantage of moves. +\effect +Valid \CppXVII{} code may fail to compile in this International Standard. +For example: +\begin{codeblock} +struct base { + base(); + base(base const &); +private: + base(base &&); +}; + +struct derived : base {}; + +base f(base b) { + throw b; // error: \tcode{base(base \&\&)} is private + derived d; + return d; // error: \tcode{base(base \&\&)} is private +} +\end{codeblock} + \rSec2[diff.cpp17.over]{\ref{over}: overloading} \diffref{over.match.oper}