<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Wording for guaranteed copy elision through simplified value categories</title>

<style type="text/css">
  ins, ins * { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  del, del * { text-decoration:line-through; background-color:#FFA0A0 }
  #hidedel:checked ~ * del, #hidedel:checked ~ * del * { display:none; visibility:hidden }

blockquote { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFBBBB;
  border: 1px solid #ECB7B7;
  padding-left: 0.5em; padding-right: 0.5em; }

blockquote.clause { counter-reset: pnum; }
blockquote.clause > p:before {
  font-weight: bold;
}
blockquote.clause > p:not(.ins):before {
  counter-increment: pnum;
  content: counter(pnum) ". ";
}
blockquote.clause > p.ins:before {
  content: counter(pnum) "+. ";
}
blockquote.clause > p.ins {
  text-decoration: underline;
  color: #000000; background-color: #C8FFC8;}
}
</style>
</head>

<body>
<div style="text-align: right; float: right">
ISO/IEC JTC1 SC22 WG21<br>
P0135R1<br>
Richard Smith<br>
richard@metafoo.co.uk<br>
2016-06-20<br>
</div>

<h1>Wording for guaranteed copy elision through simplified value categories</h1>

This paper provides wording for <a href="http://wg21.link/p0135r0">P0135R0</a>.

<p>This also resolves the following core issues:<br>
<a href="http://wg21.link/cwg1565">1565</a>: Copy elision and lifetime of <tt>initializer_list</tt> underlying array<br>
<a href="http://wg21.link/cwg1590">1590</a>: Bypassing non-copy/move constructor copying<br>
<a href="http://wg21.link/cwg1599">1599</a>: Lifetime of <tt>initializer_list</tt> underlying array<br>
<a href="http://wg21.link/cwg1697">1697</a>: Lifetime extension and copy elision<br>
<a href="http://wg21.link/cwg2022">2022</a> [PARTIAL]: Copy elision in constant expressions (except for NRVO)<br>

<p>Change in 3.10 [basic.lval] paragraph 1:

<blockquote>
Expressions are categorized according to the taxonomy in Figure 1. [Figure 1: Expression category taxonomy]

<ul>
  <li><del>An <i>lvalue</i> [&hellip;]</del>
  <li><del>[&hellip;]</del>
  <li><del>A <i>prvalue</i>[&hellip;]</del>
  <li><ins>A <i>glvalue</i> is an expression whose evaluation determines the identity of an object, bit-field, or function.</ins>
  <li><ins>A <i>prvalue</i> is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.</ins>
  <li><ins>An <i>xvalue</i> is a glvalue that denotes an object or
      bit-field whose resources can be reused (usually because it is near the
      end of its lifetime). [&nbsp;<em>Example</em>: Certain kinds of expressions
      involving rvalue references (8.3.2) yield xvalues, such as a call to a function whose
      return type is an rvalue reference or a cast to an rvalue reference type.&nbsp;]</ins>
  <li><ins>An <i>lvalue</i> is a glvalue that is not an xvalue.</ins>
  <li><ins>An <i>rvalue</i> is a prvalue or an xvalue.</ins>
</ul>

<ins>[&nbsp;<em>Note</em>:
Historically, lvalues and rvalues were so-called because
they could appear on the left- and right-hand side of an
assignment (although this is no longer generally true);
glvalues are "generalized" lvalues,
prvalues are "pure" rvalues,
and xvalues are "eXpiring" lvalues.
Despite their names, these terms classify expressions, not values.
]</ins>

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue. This property of an expression is called its <em>value category</em>. [&hellip;]
</blockquote>

<p>Add a new paragraph after 3.10 [basic.lval] paragraph 1:

<blockquote class="stdins">
The <em>result</em> of a prvalue is the value that the expression stores into
its context.
A prvalue whose result is the value
<tt>V</tt> is sometimes said to have or name the value <tt>V</tt>.
The <em>result object</em> of a prvalue
is the object initialized by the prvalue;
a prvalue that is used to compute the value of an operand of an operator
or that has type (possibly cv-qualified) <tt>void</tt> has no result object.
[&nbsp;<em>Note</em>:
Except when the prvalue is the operand of a <em>decltype-specifier</em>,
a prvalue of class or array type always has a result object.
For a discarded prvalue, a temporary object is materialized; see [expr].
]
The <em>result</em> of a glvalue is the entity denoted by the expression.
</blockquote>

<p>Change in 3.10 [basic.lval] paragraph 2:

<blockquote>
<ins>[&nbsp;<em>Note</em>:</ins>
Whenever a glvalue appears in a context where a prvalue is expected, the
glvalue is converted to a prvalue; see 4.1, 4.2, and 4.3.
<ins>]</ins>
[&nbsp;<em>Note</em>: &hellip;&nbsp;]
[&nbsp;<em>Note</em>: &hellip;&nbsp;]
</blockquote>

<p>Add a new paragraph after 3.10 [basic.lval] paragraph 2:

<blockquote class="stdins">
[&nbsp;<em>Note</em>:
Whenever a prvalue appears in a context where an xvalue or glvalue is expected,
the prvalue is converted to an xvalue; see [conv.rval].
]
</blockquote>

<p>Delete 3.10 [basic.lval] paragraphs 5 - 8 and change in paragraph 9:

<blockquote>
<del>If an expression can be used to modify the object to which it refers, the expression is called modifiable.</del>
An lvalue is <em>modifiable</em> unless its type is <tt>const</tt>-qualified or is a function type.
<ins>[&nbsp;<em>Note</em>:</ins>
A program that attempts to modify an object through a nonmodifiable lvalue <ins>expression</ins> or
<ins>through an</ins> rvalue expression is ill-formed ([expr.ass], [expr.post.inc], [expr.pre.inc]).
<ins>]</ins>
</blockquote>

<p>Change in 4.1 [conv.lval] paragraph 1, second footnote (footnote 55):

<blockquote>
In C++ class <ins>and array</ins> prvalues can have cv-qualified types<del>
(because they are objects)</del>. This differs from ISO C, in which
non-lvalues never have cv-qualified types.
</blockquote>

<p>Change in 4.1 [conv.lval] paragraph 2:

<blockquote>
When an lvalue-to-rvalue conversion is applied to an expression <tt>e</tt>, and [&hellip;] the value contained in the referenced object is not accessed.
[&nbsp;<em>Example</em>: &hellip;&nbsp;] <del>In all other cases,</del> The result of the conversion is determined according to the following rules:
<ul>
<li>If T is (possibly cv-qualified) std::nullptr_t, the result is a null pointer constant (4.10).
<li>Otherwise, if T has a class type, the conversion copy-initializes <del>a temporary of type T</del> <ins>the result object</ins> from the glvalue
    <del>and the result of the conversion is a prvalue for the temporary</del>.
<li>Otherwise, if the object to which the glvalue refers contains an invalid pointer value (3.7.4.2, 3.7.4.3),
    the behavior is implementation-defined.
<li>Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.
</ul>
</blockquote>

<p>Change in 4.2 [conv.array] paragraph 1:

<blockquote>
  An lvalue or rvalue of type "array of N T"
  or "array of unknown bound of T"
  can be converted to a prvalue of type "pointer to T".
  <ins>The temporary materialization conversion ([conv.rval]) is applied.</ins>
  The result is a pointer to the first element of the array.
</blockquote>

<p>Add a new subclause after 4.3:

<blockquote class="stdins">
<h2>4.4 Temporary materialization conversion [conv.rval]</h2>
<p>A prvalue of type <tt>T</tt> can be converted to an xvalue of type
<tt>T</tt>. This conversion initializes a temporary object ([class.temporary])
of type <tt>T</tt> from the prvalue
by evaluating the prvalue with the temporary object as its result object,
and produces an xvalue denoting the
temporary object. <tt>T</tt> shall be a complete type.
[&nbsp;<em>Note</em>:
If <tt>T</tt> is
a class type (or array thereof),
it must have an accessible and non-deleted destructor; see [class.dtor].
]
[&nbsp;<em>Example</em>:
<pre>struct X { int n; }
int k = X().n; // ok, X() prvalue is converted to xvalue
</pre>
]
</blockquote>

<p>Add a new paragraph after 5 [expr] paragraph 9 ("Whenever a glvalue expressions as an operand of an operator that expects a prvalue"):

<blockquote class="stdins">
Whenever an rvalue expression appears as an operand of an operator that expects
a glvalue for that operand, the temporary materialization
conversion ([conv.rval]) is applied to convert the expression to an xvalue.
</blockquote>

<p>Change in 5 [expr] paragraph 11:

<blockquote>
In some contexts, an expression only appears for its side effects.
Such an expression is called a <em>discarded-value expression</em>.
<del>The expression is evaluated and its value is discarded.</del>
The array-to-pointer (4.2) and function-to-pointer (4.3) standard conversions are not applied.
The lvalue-to-rvalue conversion (4.1) is applied if and
only if the expression is a glvalue of
volatile-qualified type
and it is one of the following:
[&hellip;]
[&nbsp;<em>Note</em>: Using an overloaded operator causes a function call; the above covers only operators with built-in
meaning. <ins>&nbsp;]
If the expression is a prvalue after this optional conversion,
the temporary materialization conversion ([temp.rval]) is applied.
[&nbsp;<em>Note</em>:</ins>
If the <ins>expression is an</ins> lvalue <del>is</del> of class type, it must
have a volatile copy constructor to initialize the temporary that is the result
<ins>object</ins> of the lvalue-to-rvalue conversion. ]
<ins>The glvalue expression is evaluated and its value is discarded.</ins>
</blockquote>

<em>Drafting note: it is no longer meaningful to evaluate a prvalue expression
of class or array type without specifying an object to initialize from it, as
the prvalue does not itself create such an object.</em>

<p>Change in 5.1.2 [expr.prim.lambda] paragraph 2:

<blockquote>
The evaluation of a <em>lambda-expression</em> results in a prvalue <del>temporary (12.2). This temporary is</del> <ins>whose result object is</ins> called the <em>closure object</em>. [&hellip;]
</blockquote>

<p>Change in 5.2.1 [expr.sub] paragraph 1:

<blockquote>
A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions
shall <del>have the</del><ins>be a glvalue of</ins> type "array of T" or <ins>a prvalue of type</ins> "pointer to T"
and the other shall <del>have</del> <ins>be a prvalue of</ins> unscoped enumeration or integral type.
[&hellip;] in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.
</blockquote>

<p>Change in 5.2.2 [expr.call] paragraph 4:

<blockquote>
[&hellip;]
<del>
During the initialization of a
parameter, an implementation may avoid the construction of extra temporaries by combining the conversions
on the associated argument and/or the construction of temporaries with the initialization of the parameter
(see 12.2).
</del>
<del>The</del>
<ins>It is implementation-defined whether the</ins>
lifetime of a parameter ends when the function in which it is defined returns
<ins> or at the end of the enclosing full-expression</ins>.
[&hellip;]
The <del>value</del><ins>result</ins> of a function call
is the <del>value returned by</del>
<ins>result of the operand of the
evaluated <tt>return</tt> statement
([stmt.return]) in</ins>
the called function <ins>(if any)</ins>,
except in a virtual function call
if the return type of the final overrider is different
from the return type of the statically chosen function,
the value returned from the final overrider is converted
to the return type of the statically chosen function.
</blockquote>

<p>Delete 5.2.2 [expr.call] paragraph 11:

<blockquote class="stddel">
If a function call is a prvalue of object type:
<ul><li>
if the function call is either
<ul><li>the operand of a <em>decltype-specifier</em> or
<li>the right operand of a comma operator that is the operand of a <em>decltype-specifier</em>,</ul>
a temporary object is not introduced for the prvalue.
The type of the prvalue may be incomplete.
[&nbsp;<em>Note</em>: &hellip;&nbsp;]
[&nbsp;<em>Note</em>: &hellip;&nbsp;]
<li>otherwise, the type of the prvalue shall be complete.
</blockquote>

<p>Change in 5.2.3 [expr.type.conv]:
<blockquote class="clause">
<p>
A <em>simple-type-specifier</em> (7.1.6.2) or <em>typename-specifier</em> (14.6)
followed by a parenthesized <ins>optional</ins> <em>expression-list</em>
<ins>
or by a <em>braced-init-list</em> (the initializer)
</ins>
constructs a value of the specified type given the <del>expression list</del> <ins>initializer</ins>. If the
<del>expression list</del> <ins>initializer</ins> is a <ins>parenthesized</ins>
single expression,
the type conversion expression</del>
is equivalent (in definedness, and if defined in meaning) to the corresponding
cast expression (5.4).
<ins>
  If the type is (possibly cv-qualified) <tt>void</tt> and
  the initializer is <tt>()</tt>,
  the expression
is a prvalue of the specified type that performs no initialization.
Otherwise, the expression
is a prvalue of the specified type whose result object is
direct-initialized (8.5) with the initializer.

For an expression of the form <tt>T()</tt>, <tt>T</tt> shall not be an array type.
</ins>

<del>[&hellip;]</del>

<p><del>[&hellip;]</del>
<p><del>[&hellip;]</del>
</blockquote>

<p>Change in 5.2.5 [expr.ref] paragraph 2:

<blockquote>
For the first option (dot) the first expression shall <ins>be a glvalue having</ins> <del>have</del>
complete class type. [&hellip;]
</blockquote>

<em>Drafting note: if the left operand is a prvalue, a temporary will be
materialized and it will be converted to an xvalue per [expr]/9+.</em>

<p>Change in 5.2.7 [expr.dynamic.cast] paragraph 2:

<blockquote>
[&hellip;]
If <tt>T</tt> is an rvalue reference type,
<tt>v</tt> shall be <del>an expression</del> <ins>a glvalue</ins> having a complete class type,
and the result is an xvalue of the type referred to by <tt>T</tt>.
</blockquote>

<em>Drafting note: a temporary is materialized if the operand is a prvalue.</em>

<p>Change in 5.2.9 [expr.static.cast] paragraph 3:

<blockquote>
A<ins>n</ins> <del>g</del>lvalue<del>, class prvalue, or array prvalue</del> of
type "cv1 T1" can be
cast to type "rvalue reference to cv2 T2" if "cv2 T2" is reference-compatible
with "cv1 T1" (8.5.3).
If the value is not a bit-field, the result refers to the object or the
specified base class subobject thereof; otherwise, the lvalue-to-rvalue
conversion (4.1) is applied to the bit-field and the resulting prvalue is used
as the expression of the static_cast for the remainder of this section. If T2
is an inaccessible (Clause 11) or ambiguous (10.2) base class of T1, a program
that necessitates such a cast is ill-formed.
</blockquote>

<em>Drafting note: the deleted cases would also be handled by the
immediately-following paragraph; we only need the special case above
to convert lvalues to xvalues.</em>

<p>Change in 5.2.9 [expr.static.cast] paragraph 4:

<blockquote>
An expression <tt>e</tt> can be explicitly converted to a type <tt>T</tt> using
a <tt>static_cast</tt> of the form <tt>static_cast&lt;T>(e)</tt> if
the declaration
<tt>T t(e);</tt> is well-formed, for some invented temporary
variable <tt>t</tt> (8.5).

<del>
The effect of such an explicit conversion</del>
<ins>
If <tt>T</tt> is a reference type, the effect</ins>
is the same as performing the
declaration and initialization and then using the temporary variable as the
result of the conversion.
<ins>
Otherwise, the result object is direct-initialized from <tt>e</tt>.</ins>
<del>
The expression <tt>e</tt> is used as a glvalue if and
only if the initialization uses it as a glvalue.
</del>
</blockquote>

<p>Change in 5.2.11 [expr.const.cast] paragraph 4:

<blockquote>
[&hellip;]<br>
The result of a reference <tt>const_cast</tt> refers to the original object
<ins>if the operand is a glvalue and to the result of applying the temporary
materialization conversion ([conv.rval]) otherwise</ins>.
</blockquote>

<p>Change in 5.2.8 [expr.typeid] paragraph 3:

<blockquote>
When <tt>typeid</tt> is applied to an expression other than a glvalue of a
polymorphic class type, the result refers to a <tt>std::type_info</tt> object
representing the static type of the expression. Lvalue-to-rvalue (4.1),
array-to-pointer (4.2), and function-to-pointer (4.3) conversions are not
applied to the expression.
<del>If the type of the expression is a class type, the
class shall be completely-defined.</del>
<ins>If the expression is a prvalue, the temporary materialization conversion
([conv.rval]) is applied.</ins>
The expression is an unevaluated operand (Clause 5).
</blockquote>

<p>Change in 5.3.3 [expr.sizeof] paragraph 4:

<blockquote>
The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer
(4.3) standard conversions are not applied to the operand of <tt>sizeof</tt>.
<ins>If the operand is a prvalue, the temporary materialization conversion
([conv.rval]) is applied.</ins>
</blockquote>

<em>Drafting note: this maintains the status quo. We could alternatively
remove these conversions and allow <tt>typeid</tt> and <tt>sizeof</tt> to
behave more like <tt>decltype</tt>.</em>

<p>Change in 5.5 [expr.mptr.oper] paragraph 2:

<blockquote>
The binary operator <tt>.*</tt> binds its second operand, which shall be
<ins>a glvalue</ins> of type
"pointer to member of <tt>T</tt>" to its first operand,
which shall be of class <tt>T</tt> or of a class of which <tt>T</tt> is an
unambiguous and accessible base class. The result is an object or a function of
the type specified by the second operand.
</blockquote>

<p>Change in 5.16 [expr.cond] bullet 7.1:

<blockquote>
The second and third operands have the same type; the result is of that type
<ins>and the result object is initialized using the selected operand</ins>.
<del>
If the operands have class type, the result is a prvalue temporary of the
result type, which is copy-initialized from either the second operand or the
third operand depending on the value of the first operand.
</del>
</blockquote>

<p>Change in 5.19 [expr.comma] paragraph 1:

<blockquote>
[&hellip;]
If the value of the right operand is a temporary <ins>expression</ins> (12.2), the result is that temporary <ins>expression</ins>.
</blockquote>

<p>Change in 6.6.3 [stmt.return] paragraph 2:

<blockquote>
[&hellip;]
A return statement with any other operand shall be used only in a function
whose return type is not <em>cv</em> <tt>void</tt>; the return statement
initializes the <del>object or reference to be returned</del>
<ins>glvalue result or prvalue result object of the (explicit or implicit)
function call</ins>
by copy-initialization (8.5) from the operand.
[&nbsp;<em>Note</em>:
A return statement can involve
<del>the construction and copy or move of a temporary
object (12.2).</del>
<ins>an invocation of a constructor to perform a copy or move
of the operand if it is not a prvalue or if its type differs
from the return type of the function.</ins>
A copy <del>or move</del> operation associated with a return statement may be
elided or <del>considered as an rvalue for the purpose of overload resolution
in selecting a constructor
</del>
<ins>converted to a move operation if an automatic storage duration
variable is returned</ins> (12.8).
]
[&hellip;]
</blockquote>

<em>Drafting note: while we no longer create elidable temporaries,
we still have optional elision for the NRVO cases, and still convert
copies to moves in some cases.</em>

<p>Change in 6.6.3 [stmt.return] paragraph 3:

<blockquote>
The copy-initialization of the
<del>returned entity</del> <ins>result of the call</ins>

is sequenced before [&hellip;]
</blockquote>

<p>Change in 7.1.6.2 [dcl.type.simple] paragraph 5:

<blockquote>
<ins>If the operand of a <em>decltype-specifier</em> is a prvalue,
the temporary materialization conversion is not applied ([conv.rval])
and no result object is provided for the prvalue.
The type of the prvalue may be incomplete.</ins>
[&nbsp;<em>Note</em>:
<del>
in the case where the operand of a <em>decltype-specifier</em> is a function
call and the return type of the function is a class type, a special rule
(5.2.2) ensures that the return type is not required to be complete (as it
would be if the call appeared in a sub-expression or outside of a
<em>decltype-specifier</em>).</del>
<ins>
As a result, storage is not allocated for the prvalue and it is not destroyed.
Thus, a class type is not instantiated as a result of being the type of a
function call in this context.
</ins>
In this context, the common purpose of writing the expression is merely to refer
to its type. In that sense, a <em>decltype-specifier</em> is analogous to a use
of a <em>typedef-name</em>, so the usual reasons for requiring a complete type
do not apply.  In particular, it is not necessary to allocate storage for a
temporary object or to enforce the semantic constraints associated with
invoking the type's destructor.
]
<ins>
[&nbsp;<em>Note</em>:
Unlike the preceding rule, parentheses have no special meaning in this context.
]
</ins>
[&nbsp;<em>Example</em>: &hellip;&nbsp;]
</blockquote>

<p>Change in 8.5 [dcl.init] bullet 17.6:

<blockquote>
If the destination type is a (possibly cv-qualified) class type):
<ul><li>
<ins>
If the initializer expression is a prvalue and the cv-unqualified version of
the source type is the same class as the class of the destination,
the initializer expression is used to initialize the destination object.
[&nbsp;<em>Example</em>:
<tt>T x = T(T(T()));</tt> calls the <tt>T</tt> default constructor to
initialize <tt>x</tt>. ]
</ins>
<li>
<ins>Otherwise, if</ins> <del>If</del> the initialization is
direct-initialization, or if it is copy-initialization where the cv-unqualified
version of the source type is the same class as, or a derived class of, the
class of the destination, constructors are considered. [&hellip;]
<li>
Otherwise (i.e., for the remaining copy-initialization cases), user-defined
conversion sequences that can convert from the source type to the destination
type or (when a conversion function is used) to a derived class thereof are
enumerated as described in 13.3.1.4, and the best one is chosen through
overload resolution (13.3). If the conversion cannot be done or is ambiguous,
the initialization is ill-formed. The function selected is called with the
initializer expression as its argument;
if the function is a constructor, the call
<ins>is a prvalue</ins>
<del>initializes a temporary</del>
of the cv-unqualified version of the destination type
<ins>whose return object is initialized by the constructor</ins>.
<del>The temporary is a prvalue.</del> The <del>result of the</del> call
<del>(which is the temporary for the constructor case)</del> is
<del>then</del> used to direct-initialize,
according to the rules above, the object that is the destination of the
copy-initialization.
<del>
In certain cases, an implementation is permitted to
eliminate the copying inherent in this direct-initialization by constructing
the intermediate result directly into the object being initialized; see 12.2,
12.8.
</del>
</blockquote>

<p>Change in 8.5.3 [decl.init.ref] bullet 5.2.1:

<blockquote>
If the initializer expression
<ul>
<li>
is an <del>xvalue</del> <ins>rvalue</ins>
(but not a bit-field)<del>, class prvalue, array prvalue</del>
or function lvalue and "<em>cv1</em> <tt>T1</tt>" is reference-compatible
with "<em>cv2</em> <tt>T2</tt>", or
<li>
has a class type (i.e., <tt>T2</tt> is a class type), where <tt>T1</tt> is not
reference-related to <tt>T2</tt>, and can be converted to an <del>xvalue, class
prvalue,</del> <ins>rvalue</ins> or function lvalue of type "<em>cv3</em> <tt>T3</tt>",
where "<em>cv1</em> <tt>T1</tt>" is reference-compatible with
"<em>cv3</em> <tt>T3</tt>" (see 13.3.1.6),
</ul>
then the reference is bound to the value of the initializer expression in the
first case and to the result of the conversion in the second case (or, in
either case, to an appropriate base class subobject) <ins>after applying the
temporary materialization conversion ([conv.rval])</ins>.
[&nbsp;<em>Example</em>: &hellip;&nbsp;]
</blockquote>

<em>Drafting note: this means that some cases now bind directly that did not before:
<pre>struct X {};
X &&a = X(); // binds directly
int &&b = int(); // used to not bind directly, now does</pre>
This does not appear to affect any of the places where we use the term "bind directly".
</em>

<p>Change in 8.5.3 [decl.init.ref] bullet 5.2.2:

<blockquote>
Otherwise
<ul>
<li>
If T1 or T2 is a class type and T1 is not reference-related to T2,
user-defined conversions are considered using the rules for
copy-initialization of an object of type "cv1 T1" by user-defined conversion
(8.5, 13.3.1.4, 13.3.1.5); the program is ill-formed if the corresponding
non-reference copy-initialization would be ill-formed.
The result of the
call to the conversion function, as described for the non-reference
copy-initialization,
is then used to direct-initialize the reference. For
this direct-initialization, user-defined conversions are not considered.
<li>
Otherwise, <del>a temporary of type "cv1 T1" is created and copy-initialized (8.5)
from the initializer expression. The reference is then bound to the temporary.</del>
<ins>the initializer expression is implicitly converted to a prvalue
of type "cv T1". The temporary materialization conversion is applied
and the reference is bound to the result.
</ins>
</ul>
If T1 is reference-related to T2:
<ul>
<li>cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2; and
<li>if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
</ul>
[&nbsp;<em>Example</em>: &hellip;&nbsp;]
In all cases except the last (i.e.,
<del>
creating and initializing a temporary from the initializer expression
</del>
<ins>implicitly converting the initializer expression to the underlying type of the reference</ins>),
the reference is said to <em>bind directly</em> to the initializer expression.
</blockquote>

<p>Change in 8.5.4 [dcl.init.list] bullet 3.5:

<blockquote>
Otherwise, if <tt>T</tt>
is a specialization of <tt>std::initializer_list&lt;E></tt>,
<del>
a prvalue <tt>initializer_list</tt>
</del>
<ins>the</ins>
object is constructed as described below
<del>
and used to
initialize
the object according to the rules for initialization of an object
from a class of the same type (8.5)</del>.
</blockquote>

<p>Change in 8.5.4 [dcl.init.list] bullet 3.8:

<blockquote>
Otherwise, if <tt>T</tt> is a reference type, a prvalue <del>temporary</del>
of the type referenced by <tt>T</tt> is <ins>generated.
The prvalue initializes its
result object by</ins> copy-list-initializ<del>ed</del><ins>ation</ins>
or direct-list-initializ<del>ed</del><ins>ation</ins>, depending on the kind
of initialization for the reference<del>, and the reference is bound to
that temporary</del>.
<ins>The prvalue is then used to direct-initialize the reference.</ins>
[&nbsp;<em>Note</em>: As usual, the binding will fail and the program is
ill-formed if the reference type is an lvalue reference to a non-const type. ]
</blockquote>

<p>Change in 8.5.4 [dcl.init.list] paragraph 5:

<blockquote>
An object of type <tt>std::initializer_list&lt;E></tt> is constructed from an
initializer list as if the implementation
<del>allocated a temporary</del>
<ins>generated and materialized ([conv.rval]) a prvalue of type "</ins>array of <tt>N</tt>
<del>elements of type</del> <tt>const E</tt><ins>"</ins>,
where <tt>N</tt> is the number of elements in the initializer list.
[&hellip;]
</blockquote>

<p>Change in 12.2 [class.temporary]:

<blockquote class="clause">
<p class="stdpar">
<del>Temporaries of class type</del>
<ins>Temporary objects</ins>
are created
<del>in various contexts:</del>
<ins>
when a prvalue is materialized so that it can be used as a glvalue ([conv.rval])
[&nbsp;<em>Footnote</em>:
This occurs
</ins>
<ul><li><ins>when</ins> binding a reference to a prvalue (8.5.3<ins>, 5.2.3, 5.2.7, 5.2.9, 5.2.11, 5.4</ins>),</ul>
<ins>
<ul>
<li>when initializing an object of type <tt>std::initializer_list&lt;T&gt;</tt> from a 
<i>braced-init-list</i> (8.5.4),
<li>when performing member access on a class prvalue (5.2.5, 5.5),
<li>when performing an array-to-pointer conversion or subscripting on an array prvalue (5.2.1),
<li>for certain unevaluated operands (5.2.8, 5.3.3), and
<li>when a prvalue appears as a discarded-value expression (5).
</ul>
]
</ins>
<del>
returning a prvalue (6.6.3),
a conversion that creates a prvalue (4.1, 5.2.9, 5.2.11, 5.4)</del>,
<ins>
when needed by the implementation to pass or return an object of
trivially-copyable type (see below),
and when</ins>
throwing an exception (15.1)<del>,
and
in some initializations (8.5)</del>.
[ Note: The lifetime of exception objects is described in 15.1. ]
Even when the creation of the temporary object is
unevaluated (Clause 5) <del>or otherwise avoided (12.8)</del>,
all the semantic
restrictions shall be respected as if the temporary object had been created and
later destroyed.
[ Note: This includes accessibility (11) and whether it is
deleted, for the constructor selected and for the destructor. However, in the
special case of
<del>a function call used as</del>
the operand of a <em>decltype-specifier</em>
(5.2.2), no temporary is introduced, so the foregoing does not apply to the
prvalue of any such function call. ]

<p>
<ins>The materialization of a temporary object is generally delayed as
long as possible in order to avoid creating unnecessary
temporary objects.</ins>
[&nbsp;<em>Example</em>:
Consider the following code:
<pre>
class X {
public:
  X(int);
  X(const X&amp;);
  X&amp; operator=(const X&amp;); ~X();
};
class Y {
public:
  Y(int); Y(Y&amp;&amp;); ~Y();
};
X f(X);
Y g(Y);
void h() {
  X a(1);
  X b = f(X(2));
  Y c = g(Y(3));
  a = f(a);
}
</pre>
<del>
An implementation might use a temporary in which to construct X(2) before
passing it to f() using X’s copy constructor; alternatively,</del>
X(2) <del>might be</del> <ins>is</ins>
constructed in the space used to hold <del>the</del> <ins><tt>f()</tt>'s</ins> argument<del>.
Likewise, an implementation
might use a temporary in which to construct Y(3) before passing it to g() using
Y’s move constructor; alternatively,</del>
<ins>and</ins>
Y(3) <del>might be</del> <ins>is</ins>
constructed in the space used to hold <del>the</del> <ins><tt>g()</tt>'s</ins> argument.
<del>Also,
a temporary might be used to hold the result
of f(X(2)) before copying it to b using X’s copy constructor; alternatively,
</del>
<ins>Likewise,</ins>
f()'s result <del>might be</del> <ins>is</ins> constructed <ins>directly</ins> in b<del>.
Likewise, a temporary might be used to
hold the result of g(Y(3)) before moving it to c using Y’s move constructor;
alternatively,</del>
<ins>and</ins>
g()'s result <del>might be</del> <ins>is</ins> constructed <ins>directly</ins> in c.
On the other hand, the
expression <tt>a = f(a)</tt> requires a temporary for the result of <tt>f(a)</tt>,
which is
<del>then assigned to <tt>a</tt></del>
<ins>materialized so that the reference parameter of <tt>A::operator=(const A&amp;)</tt>
  can bind to it</ins>
. ]

<p class="ins">
When an object of class type <tt>X</tt> is passed to or returned from a function, if
each copy constructor, move constructor, and destructor of <tt>X</tt> is either trivial
or deleted, and <tt>X</tt> has at least one non-deleted copy or move constructor,
implementations are permitted to create a temporary object to hold the function
parameter or result object. The temporary object is constructed
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 (even if that
constructor is inaccessible or
would not be selected by overload resolution to perform a copy or move of the
object).
[Note: This latitude is granted to allow objects of class type to be passed to
or returned from functions in registers. ]

<p> [&hellip;]
</blockquote>

<p>Change in 12.4 [class.dtor] paragraph 11 bullet 4:

<blockquote>
<ul><li>for a constructed temporary object when its lifetime ends (<ins>[conv.rval], </ins> [class.temporary])</ul>
</blockquote>

<p>Change in 12.8 [class.copy] bullet 31.1:

<blockquote>
[&hellip;]
the copy/move operation can be omitted by constructing the automatic object directly into the function <ins>call</ins>'s return <del>value</del> <ins>object</ins>
</blockquote>

<p>Delete 12.8 [class.copy] bullet 31.3:

<blockquote class="stddel">
when a temporary class object that has not been bound to a reference (12.2)
would be copied/moved to a class object with the same type (ignoring
cv-qualification), the copy/move operation can be omitted by constructing the
temporary object directly into the target of the omitted copy/move
</blockquote>

<p>Change in 12.8 [class.copy] paragraph 31's example:

<blockquote>
<pre>
class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&amp;);
};

Thing f() {
  Thing t;
  return t;
}

Thing t2 = f();
</pre>

Here the criteria for elision can <del>be combined to</del> eliminate <del>two calls to the
copy constructor of class <tt>Thing</tt>:</del> the copying of the local automatic object <tt>t</tt>
into the <del>temporary</del> <ins>result</ins> object for the <del>return
value of</del> function <ins>call</ins> <tt>f()</tt>
<del>and the copying of that temporary object into object <tt>t2</tt></del>
<ins>which is the global object <tt>t2</tt></ins>.
Effectively, the construction of the local object <tt>t</tt>
can be viewed as directly initializing the global object <tt>t2</tt>,
and that object's destruction will occur at program exit.
Adding a move constructor to <tt>Thing</tt> has the same effect,
but it is the move construction from the <del>temporary</del>
<ins>local automatic</ins> object to <tt>t2</tt> that is elided.
</blockquote>

<p>Change in 13.3.1 [over.match.funcs] paragraph 5:

<blockquote>
During overload resolution, the implied object argument is indistinguishable
from other arguments. The implicit object parameter, however, retains its
identity since
<del>
conversions on the corresponding argument shall obey these
additional rules:</del>
<ul>
<li><del>no temporary object can be introduced to hold the argument for the implicit object parameter; and</del>
<li>no user-defined conversions can be applied to achieve a type match with it.
</ul>
[&hellip;]
</blockquote>

<p>Change in 13.3.3.1 [over.best.ics] paragraph 7:

<blockquote>
In all contexts, when converting to the implicit object parameter or when
converting to the left operand of an assignment operation only standard
conversion sequences <del>that create no temporary object for the result</del>
are allowed.
</blockquote>

<em>Drafting note: standard conversion sequences never create temporary
objects, so this wording appears to be redundant before this change, and after
this change it would prevent cases like <tt>X().f()</tt>, which creates a
temporary object while binding the implicit object parameter to the
<tt>X()</tt> prvalue.</em>

<p>Change in 13.3.3.1.4 [over.ics.ref] paragraph 3:

<blockquote>
[&hellip;]
[&nbsp;<em>Note</em>:
This means, for example, that a candidate function cannot be a viable function
if it has a non-const lvalue reference parameter (other than the implicit
object parameter) and the corresponding argument <del>is a temporary or</del>
would require <del>one</del> <ins>a temporary</ins> to be created
to initialize the lvalue reference (see 8.5.3).
]
</blockquote>

<p>Change in 15.1 [except.throw] paragraph 3:

<blockquote>
Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called
the <em>exception object</em>.
<del>The temporary is an</del> <ins>An</ins> lvalue
<ins>denoting the temporary</ins>
<del>and</del> is used to initialize the
variable declared in the matching handler (15.3).
[&hellip;]
</blockquote>

<p>Change in table 19 [defaultconstructible]:

<blockquote>
a<ins>n</ins> <del>temporary</del> object of type <tt>T</tt> is value-initialized or aggregate-initialized
</blockquote>
