Skip to content

Commit

Permalink
P1825R0 Merged wording for P0527R1 and P1155R3
Browse files Browse the repository at this point in the history
 - P0527R1 Implicitly move from rvalue references in return statements
 - P1155R3 More implicit moves
  • Loading branch information
jensmaurer authored and zygoloid committed Aug 3, 2019
1 parent 1bac4eb commit 68aa22b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 12 deletions.
50 changes: 38 additions & 12 deletions source/classes.tex
Expand Up @@ -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}

Expand Down Expand Up @@ -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}%
Expand Down
29 changes: 29 additions & 0 deletions source/compatibility.tex
Expand Up @@ -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}
Expand Down

0 comments on commit 68aa22b

Please sign in to comment.