<html>
<head>
<title>Proposed wording for rvalue reference R2</title>
<style>
p {text-align:justify}
li {text-align:justify}
blockquote.note
{
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
}
ins {background-color:#FFFFA0}
del {background-color:#FFFFA0}
</style>
</head>

<body>

<address align=right>
Document number: N1952=06-0022<br>
<br>
<a href="mailto:hinnant@twcny.rr.com">Howard E. Hinnant</a><br>
2006-01-18
</address>
<hr>
<h1 align=center>A Proposal to Add an Rvalue Reference to the C++ Language</h1>
<h2 align=center>Proposed Wording</h2>
<h2 align=center>Revision 2</h2>

<h2>Revision 2 Summary and Rationale</h2>

<p>
This revision of
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1855.html">N1855</a>
has improved wording for a few sections based on the invaluable advice of the
CWG obtained at the Mont Tremblant meeting.
</p>

<p>
The specific revisions to <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1855.html">N1855</a>
are:
</p>

<ul>
<li>
Corrected numerous html errors involving "&amp;".
</li>
<li>
3.9.2p1:  Expand the definition of references to include lvalue-reference and
rvalue-reference.
</li>
<li>
5p6-7:  Reworded paragraph 6 and added paragraph 7 to both simplify and clarify
the intent.  Added an example to help clarify.
</li>
<li>
5.2.9p2:  Improved the grammar.
</li>
<li>
5.4p5:  Added "or rvalue".
</li>
<li>
6.6.3p2:  Removed the term <i>move constructor</i> from the paragraph.  Moved this
text from here to a new paragraph: 12.8p16.
</li>
<li>
7.1.3p9:  Clarified, simplified, and corrected example to match the anticipated
outcome of cwg
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#540">540</a>.
Also corrected the example in 14.3.1p4 for the same reason.
</li>
<li>
8.3.2p1:  Improved the grammar.
</li>
<li>
8.5.3p5b2:  Improved the grammar.  Added example rd4.
</li>
<li>
12.8p2: Clarified footnote.
</li>
<li>
12.8p9:  Removed sentence beginning with "Such assignment operators..." to
synch up with working draft.
</li>
<li>
12.8p15:  Reverted (removed from this proposal).  The intent is to allow cwg
issues
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#479">479</a>
and
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#535">535</a>
to both better word this paragraph, generalizing it appropriately, and expanding
the applicability to  the throw statement.
</li>
<li>
Added 12.8p16 which discusses those cases when an lvalue expression may be
considered an rvalue expression for the purpose of overload resolution of the
copy operation.  
</li>
<li>
13.3.1p5:  Slight rewording in bullet 3.
</li>
<li>
13.3.3.2p3:  Simplified.
</li>
<li>
14.3.1: (lvalue or rvalue) reference -> lvalue-reference or rvalue-reference.
</li>
<li>
14.8.2.1:  Reverted p1 and placed this specification into p3.
</li>
<li>
14.8.2.5p8:  Added line for <tt>T&amp;&amp;</tt>.
</li>
</ul>

<h2>Revision 1 Summary and Rationale</h2>

<p>
This document slightly revises
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1770.html">N1770</a>
to fix a problem found in the use of rvalue stream objects.
</p>

<p>
Consider:
</p>

<blockquote><pre>
#include &lt;ostream&gt;

class A
{
public:
    A(int i) : i_(i) {}
    int get() const {return i_;}
private:
    int i_;
};

std::ostream&amp;
operator&lt;&lt; (std::ostream&amp; os, const A&amp; a)
{
    return os &lt;&lt; a.get();
}
</pre></blockquote>

<p>
This is ill formed code according to
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1770.html">N1770</a>
:
</p>

<blockquote><pre>
    return os &lt;&lt; a.get();
Error:  {lval}ostream &lt;&lt; {rval}int is ambiguous:
std::ostream::operator&lt;&lt; (int);       // #1
operator&lt;&lt;(std::ostream&amp;, const A&amp;);  // #2
</pre></blockquote>

<p>
The first overload is a member function of <tt>ostream</tt> and thus has the
following <i>pseudo-signature</i>:
</p>

<blockquote><pre>
operator&lt;&lt;(std::ostream::operator&amp;&amp;, int);     // #1
</pre></blockquote>

<p>
To match #1, the first parameter <tt>os</tt> is converted from an lvalue to
rvalue to match the implicit object parameter and the second parameter is an
exact match.
</p>

<p>
To match #2, the first parameter is an exact match, but the second parameter is
converted via the A(int) constructor.
</p>

<p>
According to 13.3.3p1, the call is ambiguous because #1 favors the second
implicit conversion sequence while #2 favors the first implicit conversion
sequence.
</p>

<p>
We believe the source of the trouble is that
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1770.html">N1770</a>
changed the type of the implicit object parameter from an lvalue-reference to an
rvalue-reference (which was motivated by eliminating one exception to the
general rules of the language).
</p>

<p>
This revision corrects that mistake by reverting the type of the implicit object
parameter to an lvalue-reference (as it is in C++03), and adding a clarification
to the special treatment that the implicit object parameter already receives
during overload resolution: An rvalue to lvalue conversion to match the implicit
object parameter does not affect overload resolution (which is also true in
C++03).
</p>

<p>
The specific revisions to
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1770.html">N1770</a>
are:
</p>

<ul>
<li>
13.3.1p4 : Revert to the current WP version.  This makes the implicit object
parameter a <tt><i>cv</i> X&amp;</tt> again.
</li>
<li>
13.3.1p5 : N1770 strikes the 3rd bullet which states that you can bind an rvalue
to the implicit object parameter even if it is a non-const lvalue-reference.
This bullet is now added back, and clarified that such binding will not impact
overload resolution.
</li>
<li>
13.3.3.1.4p3 : N1770 deleted two parenthetical phrases referring to the fact
that an rvalue can bind to the implicit object parameter.  This revision places
the phrases back in their original form.
</li>
<li>
13.3.3.2p3 : Added both normative wording and example to the N1770 proposed
bullet to stress that l/rvalue-ness does not affect rankings involving an
implicit object parameter.
</li>
</ul>

<h2>Introduction</h2>
<p>
The purpose of this document is to provide proposed wording for the <i>rvalue
reference</i> proposal documented by <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">N1690</a>
and <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">N1377</a>.
</p>

<p>
The proposed wording herein avoids defining the terms <i>move constructor</i>
and <i>move assignment</i> in order to avoid possible conflict or confusion with
similar
terms which we wish to introduce into the library.  <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html">N1771</a>
introduces <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt> requirements,
defining these concepts in terms of expressions and post-conditions, instead of
in terms of constructors or function signatures.
</p>

<h2>3.9.2 - Compound types</h2>

<p>
-1- Compound types can be constructed in the following ways:
</p>
<ul>
<li>...</li>
<li>
<i>references</i> to objects or functions of a given type, 8.3.2<del>;</del><ins>.
There are two types of references:</ins>
<ul>
<li><ins>
<i>lvalue-reference</i>
</ins></li>
<li><ins>
<i>rvalue-reference</i>
</ins></li>
</ul>
</li>
<li>...</li>
</ul>
<h2>3.10 - Lvalues and rvalues</h2>

<p>
-5- The result of calling a function that does not return <del>a reference</del>
<ins>an lvalue-reference</ins> is an rvalue. User defined operators are
functions, and whether such operators expect or yield lvalues is determined by
their parameter and return types.
</p>
<p>
-6- An expression which holds a temporary object resulting from a cast to a
<del>nonreference type</del><ins>type other than an lvalue-reference type</ins>
is an rvalue (this includes the explicit creation of an object using functional
notation (5.2.3)).
</p>

<h2>4 - Standard conversions</h2>

<p>
-3- An expression <tt>e</tt> can be <i>implicitly converted</i> to a type
<tt>T</tt> if and only if the declaration ``<tt>T t=e;</tt>'' is well-formed,
for some invented temporary variable <tt>t</tt> (dcl.init). The effect of the
implicit conversion is the same as performing the declaration and initialization
and then using the temporary variable as the result of the conversion. The
result is an lvalue if <tt>T</tt> is <del>a reference</del> <ins>an
lvalue-reference</ins> type (dcl.ref), and an rvalue otherwise. The expression
<tt>e</tt> is used as an lvalue if and only if the initialization uses it as an
lvalue.
</p>

<h2>5 - Expressions</h2>

<p>
-6- If an expression initially has the type ``<ins>lvalue-</ins>reference to <tt>T</tt>''
(dcl.ref, dcl.init.ref), the type is adjusted to ``<tt>T</tt>'' prior to any
further analysis, the expression designates the object
or function denoted by the <ins>lvalue-</ins>reference, and the expression is an lvalue.
</p>

<p>
<ins>-7- If an expression initially has the type ``<ins>rvalue-</ins>reference to <tt>T</tt>''
(dcl.ref, dcl.init.ref), the type is adjusted to ``<tt>T</tt>'' prior to any
further analysis, and the expression designates the object
or function denoted by the rvalue-reference.  If the expression is the result of
calling a function, whether implicitly or explicitly, it is an rvalue;
otherwise, it is an lvalue.<br>
[<i>Example:</i></ins>
</p>

<blockquote><pre><ins>
struct A {};
A&amp;&amp; operator+(A,A);
A&amp;&amp; f();
...
A a;
A&amp;&amp; ar = a;
</ins></pre></blockquote>

<p><ins>
The expressions <tt>f()</tt> and <tt>a + a</tt> are rvalues.  The expression
<tt>ar</tt> is an lvalue of type <tt>A</tt>.<br>
--<i>end example</i>]
</ins></p>

<h2>5.2.2 - Function call</h2>

<p>
-10- A function call is an lvalue if and only if the result type is <del>a
reference</del> <ins>an lvalue-reference</ins>.
</p>

<h2>5.2.7 - Dynamic cast</h2>

<p>
-2- If <tt>T</tt> is a pointer type, <tt>v</tt> shall be an rvalue of a pointer
to complete class type, and the result is an rvalue of type <tt>T</tt>. If
<tt>T</tt> is <del>a reference</del><ins>an lvalue-reference</ins> type,
<tt>v</tt> shall be an lvalue of a complete class type, and the result is an
lvalue of the type referred to by <tt>T</tt>.  <ins>If <tt>T</tt> is an
rvalue-reference type, <tt>v</tt> shall be an expression having a complete class
type, and the result is an rvalue of the type referred to by <tt>T</tt>.</ins>
</p>

<p>
-5- If <tt>T</tt> is ``pointer to <tt><i>cv1</i> B</tt>'' and <tt>v</tt> has
type ``pointer to <tt><i>cv2</i> D</tt>'' such that <tt>B</tt> is a base class
of <tt>D</tt>, the result is a pointer to the unique <tt>B</tt> sub-object of
the <tt>D</tt> object pointed to by <tt>v</tt>. Similarly, if <tt>T</tt> is
``reference to <tt><i>cv1</i> B</tt>'' and <tt>v</tt> has type ``<tt><i>cv2</i>
D</tt>'' such that <tt>B</tt> is a base class of <tt>D</tt>, the result is
<del>an lvalue for</del> the unique <tt>B</tt> sub-object of the <tt>D</tt>
object referred to by <tt>v</tt>.  <ins>The result is an lvalue if <tt>T</tt> is
an lvalue-reference, or an rvalue if <tt>T</tt> is an rvalue-reference.</ins>
</p>
<blockquote>...</blockquote>

<h2>5.2.9 - Static cast</h2>

<p>
-1- The result of the expression <tt>static_cast&lt;T&gt;(v)</tt> is the result
of converting the expression <tt>v</tt> to type <tt>T</tt>. If <tt>T</tt> is
<del>a reference</del> <ins>an lvalue-reference</ins> type, the result is an
lvalue; otherwise, the result is an rvalue. Types shall not be defined in a
<tt>static_cast</tt>. The <tt>static_cast</tt> operator shall not cast away
constness (expr.const.cast).
</p>

<p>
-2- An lvalue of type ``<tt><i>cv1</i> B</tt>'', where <tt>B</tt> is a class
type, can be cast to type ``reference to <tt><i>cv2</i> D</tt>'', where
<tt>D</tt> is a class derived (clause class.derived) from <tt>B</tt>, if a valid
standard conversion from ``pointer to <tt>D</tt>'' to ``pointer to <tt>B</tt>''
exists (conv.ptr), <tt><i>cv2</i></tt> is the same cv-qualification as, or
greater cv-qualification than, <tt><i>cv1</i></tt>, and <tt>B</tt> is not a
virtual base class of <tt>D</tt>.

The result <del>is an lvalue of</del> <ins>has</ins> type
``<tt><i>cv2</i> D</tt><del>.</del>'' <ins>if the type cast to is an
lvalue-reference; otherwise the result is an rvalue. </ins>

<ins>An rvalue of type
``<tt><i>cv1</i> B</tt>'' can be cast to type ``rvalue-reference to
<tt><i>cv2</i> D</tt>'' with the same constraints as noted for the lvalue of
type ``<tt><i>cv1</i> B</tt>,'' resulting in an rvalue.</ins> If the
<del>lvalue</del> <ins>object</ins> of type ``<tt><i>cv1</i> B</tt>'' is
actually a sub-object of an object of type <tt>D</tt>, the <del>lvalue</del>
<ins>result</ins> refers to the enclosing object of type <tt>D</tt>. Otherwise,
the result of the cast is undefined.
</p>

<blockquote>...</blockquote>

<p>
-3- Otherwise, 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&gt;(e)</tt> if the declaration ``<tt>T t(e);</tt>'' is
well-formed, for some invented temporary variable <tt>t</tt> (dcl.init). The
effect of such an explicit conversion is the same as performing the declaration
and initialization and then using the temporary variable as the result of the
conversion. The result is an lvalue if <tt>T</tt> is <del>a reference</del>
<ins>an lvalue-reference</ins> type (dcl.ref), and an rvalue otherwise. The
expression <tt>e</tt> is used as an lvalue if and only if the initialization
uses it as an lvalue.
</p>

<h2>5.2.10 - Reinterpret cast</h2>

<p>
-1- The result of the expression <tt>reinterpret_cast&lt;T&gt;(v)</tt> is the
result of converting the expression <tt>v</tt> to type <tt>T</tt>. If <tt>T</tt>
is <del>a reference</del> <ins>an lvalue-reference</ins> type, the result is an
lvalue; otherwise, the result is an rvalue and the lvalue-to-rvalue (conv.lval),
array-to-pointer (conv.array), and function-to-pointer (conv.func) standard
conversions are performed on the the expression <tt>v</tt>. Types shall not be
defined in a <tt>reinterpret_cast</tt>. Conversions that can be performed
explicitly using <tt>reinterpret_cast</tt> are listed below. No other conversion
can be performed explicitly using <tt>reinterpret_cast</tt>.
</p>

<p>
-11- An lvalue expression of type <tt>T1</tt> can be cast to the type
``reference to <tt>T2</tt>'' if an expression of type ``pointer to <tt>T1</tt>''
can be explicitly converted to the type ``pointer to <tt>T2</tt>'' using a
<tt>reinterpret_cast</tt>. That is, a reference cast
<tt>reinterpret_cast&lt;T&amp;&gt;(x)</tt> has the same effect as the conversion
<tt>*reinterpret_cast&lt;T*&gt;(&amp;x)</tt> with the built-in <tt>&amp;</tt> and
<tt>*</tt> operators <ins>(and similarly for
<tt>reinterpret_cast&lt;T&amp;&amp;&gt;(x)</tt>)</ins>.   The result <del>is an
lvalue that</del> refers to the same
object as the source lvalue, but with a different type. <ins>The result is an
lvalue for lvalue-references or an rvalue for rvalue-references.</ins> No
temporary is created, no copy is made, and constructors (class.ctor) or
conversion functions (class.conv) are not called.
</p>

<h2>5.2.11 - Const cast</h2>

<p>
-1- The result of the expression <tt>const_cast&lt;T&gt;(v)</tt> is of type
<tt>T</tt>. If <tt>T</tt> is <del>a reference</del> <ins>an
lvalue-reference</ins> type, the result is an lvalue; otherwise, the result is
an rvalue and, the lvalue-to-rvalue (conv.lval), array-to-pointer (conv.array),
and function-to-pointer (conv.func) standard conversions are performed on the
expression <tt>v</tt>. Types shall not be defined in a <tt>const_cast</tt>.
Conversions that can be performed explicitly using <tt>const_cast</tt> are
listed below. No other conversion shall be performed explicitly using
<tt>const_cast</tt>.
</p>

<p>
-4- An lvalue of type <tt>T1</tt> can be explicitly converted to an lvalue of
type <tt>T2</tt> using the cast <tt>const_cast&lt;T2&amp;&gt;</tt> (where
<tt>T1</tt> and <tt>T2</tt> are object types) if a pointer to <tt>T1</tt> can be
explicitly converted to the type pointer to <tt>T2</tt> using a const_cast.
<ins>Similarly, an expression of type <tt>T1</tt> can be explicitly converted to
an rvalue of type <tt>T2</tt> using the cast <tt>const_cast&lt;T2&amp;&amp;&gt;</tt>
(where <tt>T1</tt> and <tt>T2</tt> are object types) if a pointer to <tt>T1</tt>
can be explicitly converted to the type pointer to <tt>T2</tt> using a
<tt>const_cast</tt>.</ins> The result of a reference <tt>const_cast</tt> refers
to the original object.
</p>

<h2>5.4 - Explicit type conversion (cast notation)</h2>

<p>
-1- The result of the expression <tt>(T)</tt> <i>cast-expression</i> is of type
<tt>T</tt>. The result is an lvalue if <tt>T</tt> is <del>a reference</del>
<ins>an lvalue-reference</ins> type, otherwise the result is an rvalue. [Note:
if <tt>T</tt> is a non-class type that is cv-qualified, the cv-qualifiers are
ignored when determining the type of the resulting rvalue; see basic.lval. ]
</p>

<p>
-5- The conversions performed by
</p>

<ul>
<li>a <tt>const_cast</tt> (5.2.11),</li>
<li>a <tt>static_cast</tt> (5.2.9),</li>
<li>a <tt>static_cast</tt> followed by a <tt>const_cast</tt>,</li>
<li>a <tt>reinterpret_cast</tt> (5.2.10), or</li>
<li>a <tt>reinterpret_cast</tt> followed by a <tt>const_cast</tt>,</li>
</ul>

<p>
can be performed using the cast notation of explicit type conversion. The same
semantic restrictions and behaviors apply, with the exception that in performing
a <tt>static_cast</tt> in the following situations the conversion is valid even
if the base class is inaccessible:
</p>

<ul>
<li>
a pointer to an object of derived class type or an lvalue <ins>or rvalue</ins>
of derived class type may be explicitly converted to a pointer or reference to
an unambiguous base class type, respectively;
</li>
<li>
a pointer to member of derived class type may be explicitly converted to a
pointer to member of an unambiguous non-virtual base class type;
</li>
<li>
a pointer to an object of an unambiguous non-virtual base class type, an lvalue
<ins>or rvalue</ins> of an unambiguous non-virtual base class type, or a pointer
to member of an unambiguous non-virtual base class type may be explicitly
converted to a pointer, a reference, or a pointer to member of a derived class
type, respectively.
</li>
</ul>

<p>...</p>

<h2>5.16 - Conditional operator</h2>

<p>
-3- Otherwise, if the second and third operand have different types ...
</p>

<ul>
<li>
If <tt>E2</tt> is an lvalue: <tt>E1</tt> can be converted to match <tt>E2</tt>
if <tt>E1</tt> can be implicitly converted (clause conv) to the type
``<ins>lvalue-</ins>reference to <tt>T2</tt>'', subject to the constraint that
in the conversion the reference must bind directly (dcl.init.ref) to
<tt>E1</tt>.
</li>
<li>...</li>
</ul>

<h2>6.6.3 - The return statement</h2>

<p>
-2- A return statement without an expression can be used only in functions that
do not return a value, that is, a function with the return type <tt>void</tt>, a
constructor (class.ctor), or a destructor (class.dtor). A return statement with
an expression of non-void type can be used only in functions returning a value;
the value of the expression is returned to the caller of the function. The
expression is implicitly converted to the return type of the function in which
it appears. A return statement can involve the construction and copy of a
temporary object (class.temporary). <ins>A copy operation associated with a
return statement may be elided or considered as an rvalue for the purpose of
overload resolution in selecting a constructor (12.8).</ins>
Flowing off the end of a function is
equivalent to a <tt>return</tt> with no value; this results in undefined
behavior in a value-returning function.
</p>

<h2>7.1.3 - The typedef specifier</h2>

<p>
-9- If a typedef <tt>TD</tt> names a type <del>``reference to <tt><i>cv1</i> S</tt>''</del>
<ins>that is an lvalue-reference or rvalue-reference to a type <tt>T</tt></ins>,
an attempt to create the type <del>``reference to <tt><i>cv2</i> TD</tt>''</del>
<ins>``lvalue-reference to <tt><i>cv</i> TD</tt>''</ins> creates the
type  <del>``reference to <tt><i>cv12</i> S</tt>'', where <tt><i>cv12</i></tt> is the
union of the cv-qualifiers <tt><i>cv1</i></tt> and <tt><i>cv2</i></tt>. 
Redundant qualifiers are ignored</del> <ins>``lvalue-reference to <tt>T</tt>'',
while an attempt to create the type ``rvalue-reference to <tt><i>cv</i> TD</tt>''
creates the type <tt>TD</tt></ins>. <br> [<i>Example:</i>
</p>

<blockquote><pre><del>
int i;
typedef int &amp; RI;
RI &amp; r1 = i; / / r1 has the type int&amp;
const RI &amp; r2 = i; / / r2 has the type const int&amp;
</del>
<ins>
int i;
typedef int&amp;  LRI;
typedef int&amp;&amp; RRI;
LRI&amp; r1 = i;            // r1 has the type int&amp;
const LRI&amp; r2 = i;      // r2 has the type int&amp;
const LRI&amp;&amp; r3 = i;     // r3 has the type int&amp;
RRI&amp; r4 = i;            // r4 has the type int&amp;
RRI&amp;&amp; r5 = i;           // r5 has the type int&amp;&amp;
</ins></pre></blockquote>
<p>
--<i>end example</i>]
</p>

<h2>8 - Declarators</h2>

<p>-4- Declarators have the syntax</p>

<blockquote><pre>
declarator:
    direct-declarator
    ptr-operator declarator

direct-declarator:
    declarator-id
    direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq<sub>opt</sub> exception-specification<sub>opt</sub>
    direct-declarator [ constant-expression<sub>opt</sub> ]
    ( declarator )

ptr-operator:
    * cv-qualifier-seq<sub>opt</sub>
    &amp;
    <ins>&amp;&amp;</ins>
    ::<sub>opt</sub> nested-name-specifier * cv-qualifier-seq<sub>opt</sub>

cv-qualifier-seq:
    cv-qualifier cv-qualifier-seq<sub>opt</sub>
...
</pre></blockquote>

<h2>8.3.2 - References</h2>

<p>
-1- In a declaration <tt>T D</tt> where <tt>D</tt> has <ins>either of</ins>
the form<ins>s</ins>
</p>

<blockquote><pre>
&amp;  D1
<ins>&amp;&amp; D1</ins>
</pre></blockquote>

<p>
and the type of the identifier in the declaration <tt>T D1</tt> is
<i>``derived-declarator-type-list</i> <tt>T</tt>,'' then the type of the
identifier of <tt>D</tt> is <i>``derived-declarator-type-list</i> reference to
<tt>T</tt>.'' Cv-qualified references are ill-formed except when the
cv-qualifiers are introduced through the use of a typedef (dcl.typedef) or of a
template type argument (temp.arg), in which case the cv-qualifiers are ignored.
[<i>Example:</i> in
</p>

<blockquote><pre>
typedef int&amp; A;
const A aref = 3;               //  ill-formed;
                //  non-const  reference initialized with rvalue
</pre></blockquote>

<p>
the type of <tt>aref</tt> is ``reference to <tt>int</tt>'', not ``<tt>const</tt>
reference to int''.] [<i>Note:</i> a reference can be thought of as a name of an
object. ] A declarator that specifies the type ``reference to cv void'' is
ill-formed.
</p>

<p><ins>
A reference type that is declared using <tt>&amp;</tt> is called an
<i>lvalue-reference</i>, and a reference type that is declared using <tt>&amp;&amp;</tt> is
called an <i>rvalue-reference</i>. Lvalue-references and rvalue-references are distinct
types. Except where explicitly noted, they are semantically equivalent and
commonly referred to as references.
</ins></p>

<h2>8.5.3 - References</h2>

<p>
<i>Note: The changes proposed for core issue 391 are reflected in the "old" text
below.</i>
</p>

<p>
-1- A variable declared to be a <tt>T&amp;</tt> <ins>or <tt>T&amp;&amp;</tt></ins>, that is
``reference to type <tt>T</tt>'' (dcl.ref), shall be initialized by an object,
or function, of type <tt>T</tt> or by an object that can be converted into a
<tt>T</tt>.
</p>

<p>
-5- A reference to type ``<tt><i>cv1</i> T1</tt>'' is initialized by an
expression of type ``<tt><i>cv2</i> T2</tt>'' as follows:
</p>
<ul>
<li>If the initializer expression
<ul>
<li>
is an lvalue (but is not a bit-field), and ``<tt><i>cv1</i> T1</tt>'' is
reference-compatible with ``<tt><i>cv2</i> T2</tt>,'' or
</li>
<li>
has a class type (i.e., <tt>T2</tt> is a class type) and can be implicitly
converted to an lvalue of type ``<tt><i>cv3</i> T3</tt>,'' where
``<tt><i>cv1</i> T1</tt>'' is reference-compatible with ``<tt><i>cv3</i>
T3</tt>'' *
<blockquote>
[Footnote: This requires a conversion function (class.conv.fct) returning a
reference type. --- end foonote] </blockquote> (this conversion is selected by
enumerating the applicable conversion functions (over.match.ref) and choosing
the best one through overload resolution (over.match)), </li> </ul>  then the
reference is bound directly to the initializer expression lvalue in the first
case, and the reference is bound to the lvalue result of the conversion in the
second case. In these cases the reference is said to <i>bind directly</i> to the
initializer expression. [<i>Note:</i> the usual lvalue-to-rvalue (conv.lval),
array-to-pointer (conv.array), and function-to-pointer (conv.func) standard
conversions are not needed, and therefore are suppressed, when such direct
bindings to lvalues are done. ]<br> [<i>Example:</i>
<blockquote><pre>
double d = 2.0;
double&amp; rd = d;                  // rd <i>refers to</i> d
const double&amp; rcd = d;           // rcd <i>refers to</i> d

struct A { };
struct B : public A { } b;
A&amp; ra = b;                       // ra <i>refers to</i> A <i>sub-object in</i> b
const A&amp; rca = b;                // rca <i>refers to</i> A <i>sub-object in</i> b
</pre></blockquote>
-- <i>end example</i>]
</li>
<li>
Otherwise, the reference shall be <ins>an lvalue-reference</ins> to a
non-volatile const type (i.e., <tt><i>cv1</i></tt>
shall be <tt>const</tt>)<ins>, or shall be an rvalue-reference</ins>. [<i>Example:</i>
<blockquote><pre>
double&amp; rd2 = 2.0;    // <i>error: not an lvalue and reference not</i> const
int  i = 2;
double&amp; rd3 = i;      // <i>error: type mismatch and reference not</i> const
<ins>double&amp;&amp; rd4 = i;     // <i>OK, reference bound to temporary double</i></ins>
</pre></blockquote>
-- <i>end example</i>]
<ul>
<li>
If the initializer expression is an rvalue, with <tt>T2</tt> a class type, and
``<tt><i>cv1</i> T1</tt>" is reference-compatible with ``<tt><i>cv2</i>
T2</tt>," the reference is bound to the object represented by the rvalue (see
basic.lval) or to a sub-object within that object. [<i>Example:</i>
<blockquote><pre>
struct A { };
struct B : public A { } b;
extern B f();
const A&amp; rca = f();        // <i>Bound to the </i>A<i> sub-object of the </i>B<i> rvalue</i>
<ins>A&amp;&amp; rcb = f();             // <i>Same as above</i></ins>
</pre></blockquote>
-- <i>end example</i>]
</li>
<li>
Otherwise, a temporary of type ``<tt><i>cv1</i> T1</tt>" is created and
initialized from the initializer expression using the rules for a non-reference
copy initialization (dcl.init). The reference is then bound to the temporary. If
<tt>T1</tt> is reference-related to <tt>T2</tt>, <tt><i>cv1</i></tt> must be the
same cv-qualification as, or greater cvqualification than, <tt><i>cv2</i></tt>;
otherwise, the program is ill-formed.  [<i>Example:</i>
<blockquote><pre>
const double&amp; rcd2 = 2;        // rcd2 <i>refers to temporary with value</i> 2.0
<ins>double&amp;&amp; rcd3 = 2;             // rcd3 <i>refers to temporary with value</i> 2.0</ins>
const volatile int cvi = 1;
const int&amp; r = cvi;            // <i>error: type qualifiers dropped</i>
</pre></blockquote>
-- <i>end example</i>] </li> </ul>
</li>
</ul>

<h2>12.8 - Copying class objects</h2>

<p>
-2- A non-template constructor for class <tt>X</tt> is a <i>copy</i> constructor
if its first parameter is of type <tt>X&amp;</tt>, <tt>const X&amp;</tt>, <tt>volatile
X&amp;</tt> or <tt>const volatile X&amp;</tt>, and either there are no other parameters
or else all other parameters have default arguments (dcl.fct.default).*
</p>

<blockquote><p>
[Footnote: Because a template constructor <ins>or a constructor whose first
parameter is an rvalue-reference</ins> is never a copy constructor, the
presence of such a <del>template</del> <ins>constructor</ins> does not suppress
the implicit declaration of a copy constructor.
<del>Template</del> <ins>Such</ins> constructors participate in overload
resolution with other constructors, including copy constructors, and<ins>, if
selected, will</ins> <del>a template
constructor may</del> be used to copy an
object if it provides a better match than other constructors. --- end
foonote]
</p></blockquote>

<p>
[<i>Example:</i> <tt>X::X(const X&amp;)</tt> and <tt>X::X(X&amp;, int=1)</tt> are copy
constructors.
</p>

<blockquote><pre>
class X {
    //  ...
public:
    X(int);
    X(const X&amp;, int = 1);
};
X a(1);                         //  calls  X(int);
X b(a, 0);                      //  calls  X(const   X&amp;,   int);
X c = b;                        //  calls  X(const   X&amp;,   int);
</pre></blockquote>

<p>
--- end example] [<i>Note:</i> all forms of copy constructor may be declared for
a class. [<i>Example:</i>
</p>

<blockquote><pre>
class X {
        //  ...
public:
        X(const X&amp;);
        X(X&amp;);                  //  OK
};
</pre></blockquote>

<p>
--- end example]<br> --- end note] [<i>Note:</i> if a class <tt>X</tt> only has
a copy constructor with a parameter of type <tt>X&amp;</tt>, an initializer of type
<tt>const X</tt> or <tt>volatile X</tt> cannot initialize an object of type
(possibily cv-qualified) <tt>X</tt>. [<i>Example:</i>
</p>

<blockquote><pre>
struct X {
        X();                    //  default constructor
        X(X&amp;);                  //  copy constructor with a nonconst parameter
};
const X cx;
X x = cx;                       //  error -  X::X(X&amp;)  cannot copy  cx  into  x
</pre></blockquote>

<p>
--- end example]<br> --- end note]
</p>

<p>
-9- A user-declared <i>copy</i> assignment operator <tt>X::operator=</tt> is a
non-static non-template member function of class <tt>X</tt> with exactly one
parameter of type <tt>X</tt>, <tt>X&amp;</tt>, <tt>const X&amp;</tt>, <tt>volatile
X&amp;</tt> or <tt>const volatile X&amp;</tt>.*
</p>

<blockquote><p>
[Footnote: Because a template assignment operator <ins>or an assignment operator
taking an rvalue reference parameter</ins> is never a copy assignment operator,
the presence of such <del>a template</del> <ins>an assignment operator</ins>
does not suppress the implicit declaration of a copy assignment operator.
<del>Template</del><ins>Such</ins> assignment operators participate in overload
resolution with other assignment operators, including copy assignment operators,
and<ins>, if selected will</ins> <del>a template assignment operator may</del>
be used to assign an object <del>if it provides a better match than other
assignment operators</del>. --- end foonote]
</p></blockquote>

<p>
[<i>Note:</i> an overloaded assignment operator must be declared to have only
one parameter; see over.ass. ] [<i>Note:</i> more than one form of copy
assignment operator may be declared for a class. ] [<i>Note:</i> if a class
<tt>X</tt> only has a copy assignment operator with a parameter of type
<tt>X&amp;</tt>, an expression of type <tt>const X</tt> cannot be assigned to an
object of type <tt>X</tt>. [<i>Example:</i>
</p>

<blockquote><pre>
struct X {
        X();
        X&amp; operator=(X&amp;);
};
const X cx;
X x;
void f() {
        x = cx;                 //  error:
                                //   X::operator=(X&amp;)  cannot assign  cx  into  x
}
</pre></blockquote>

<p>
--- end example]<br> --- end note]
</p>

<p>
-15- When certain criteria are met ...
</p>

<p><ins>
-16- When the above criteria are met for omitting the copy operation of a class
object, and if the class type designated by the expression
(say <tt><i>cv1</i> T</tt>) has a constructor whose first parameter is 
<tt><i>cv2</i> T&amp;&amp;</tt>, where <tt><i>cv2</i></tt> is the same
cv-qualification as, or greater cv-qualification than, <tt><i>cv1</i></tt>,
and all other parameters have default arguments, then the 
expression is considered to be an rvalue for the process of overload
resolution used to select the constructor for the copy operation.
</ins></p>

<p><ins>[<i>Example:</i></ins></p>

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

Thing f(bool b) {
    Thing t;
    if (b)
        throw t; // <i>OK, Thing(Thing&amp;&amp;) used (or elided) to throw t</i>
    return t;    // <i>OK, Thing(Thing&amp;&amp;) used (or elided) to return t</i>
}

Thing t2 = f();  // <i>OK, Thing(Thing&amp;&amp;) used (or elided) for construction of t2</i>
</ins></pre></blockquote>

<p><ins>--- end example]</ins></p>

<h2>13.3.1 - Candidate functions and argument lists</h2>

<p>
-5- During overload resolution, the implied object argument is indistinguishable
from other arguments. The implicit object parameter, however, retains its
identity since conversions on the corresponding argument shall obey these
additional rules:
</p>
<ul>
<li>
no temporary object can be introduced to hold the argument for the implicit
object parameter;<ins> and</ins>
</li>
<li>
no user-defined conversions can be applied to achieve a type match with it;
and
</li>
<li>
even if the implicit object parameter is not const-qualified, an rvalue
temporary can be bound to the parameter as long as in all other respects the
temporary can be converted to the type of the implicit object parameter.
<ins>[<i>Note:</i> The fact that such a temporary is an rvalue does not affect
the ranking of implicit conversion sequences (13.3.3.2). <i>-- end note</i>]</ins>
</li>
</ul>

<h2>13.3.1.4 - Copy-initialization of class by user-defined conversion</h2>

<p>
-1- Under the conditions specified in dcl.init, as part of a copy-initialization
of an object of class type, a user-defined conversion can be invoked to convert
an initializer expression to the type of the object being initialized. Overload
resolution is used to select the user-defined conversion to be invoked. Assuming
that ``<tt><i>cv1</i> T</tt>'' is the type of the object being initialized, with
<tt>T</tt> a class type, the candidate functions are selected as follows:
</p>

<ul>
<li>
The converting constructors (class.conv.ctor) of <tt>T</tt> are candidate
functions.
</li>
<li>
When the type of the initializer expression is a class type ``<tt><i>cv</i>
S</tt>'', the conversion functions of <tt>S</tt> and its base classes are
considered. Those that are not hidden within <tt>S</tt> and yield a type whose
cv-unqualified version is the same type as <tt>T</tt> or is a derived class
thereof are candidate functions. Conversion functions that return ``reference to
<tt>X</tt>'' return lvalues <ins>or rvalues (depending upon the type of
reference)</ins> of type <tt>X</tt> and are therefore considered to yield
<tt>X</tt> for this process of selecting candidate functions.
</li>
</ul>

<h2>13.3.1.5 - Initialization by conversion function</h2>

<p>
-1- Under the conditions specified in dcl.init, as part of an initialization of
an object of nonclass type, a conversion function can be invoked to convert an
initializer expression of class type to the type of the object being
initialized. Overload resolution is used to select the conversion function to be
invoked. Assuming that ``<tt><i>cv1</i> T</tt>'' is the type of the object being
initialized, and ``<tt><i>cv</i> S</tt>'' is the type of the initializer
expression, with <tt>S</tt> a class type, the candidate functions are selected
as follows:
</p>

<ul>
<li>
The conversion functions of <tt>S</tt> and its base classes are considered.
Those that are not hidden within <tt>S</tt> and yield type <tt>T</tt> or a type
that can be converted to type <tt>T</tt> via a standard conversion sequence
(over.ics.scs) are candidate functions. Conversion functions that return a
cv-qualified type are considered to yield the cv-unqualified version of that
type for this process of selecting candidate functions. Conversion functions
that return ``reference to <tt><i>cv2</i> X</tt>'' return lvalues <ins>or
rvalues (depending upon the type of reference)</ins> of type ``<tt><i>cv2</i>
X</tt>'' and are therefore considered to yield <tt>X</tt> for this process of
selecting candidate functions.
</li>
</ul>

<h2>13.3.1.6 Initialization by conversion function for direct reference binding</h2>
<p>
-1- Under the conditions specified in dcl.init.ref, a reference can be bound
directly to an lvalue that is the result of applying a conversion function to an
initializer expression. Overload resolution is used to select the conversion
function to be invoked. Assuming that ``<i>cv1</i> <tt>T</tt>'' is the
underlying type of the reference being initialized, and ``<i>cv</i> <tt>S</tt>''
is the type of the initializer expression, with <tt>S</tt> a class type, the
candidate functions are selected as follows:
</p>
<ul>
<li>
The conversion functions of <tt>S</tt> and its base classes are considered.
Those that are not hidden within <tt>S</tt> and yield type
``<ins>lvalue-</ins>reference to <i>cv2</i> <tt>T2</tt>'', where ``<i>cv1</i>
<tt>T</tt>'' is reference-compatible (dcl.init.ref) with ``<i>cv2</i>
<tt>T2</tt>'', are candidate functions.
</li>
</ul>

<h2>13.3.3.1.4 - Reference binding</h2>

<p>
-3- A standard conversion sequence cannot be formed if it requires binding
<del>a reference</del> <ins>an lvalue-reference</ins> to non-const to an rvalue
(except when binding an implicit object parameter; see the special rules for
that case in over.match.funcs). [<i>Note:</i> this means, for example, that a
candidate function cannot be a viable function if it has a non-const
<ins>lvalue-</ins>reference parameter (other than the implicit object parameter)
and the corresponding argument is a temporary or would require one to be created
to initialize the <ins>lvalue-</ins>reference (see dcl.init.ref). ]
</p>

<p>
-4- Other restrictions on binding a reference to a particular argument do not
affect the formation of a standard conversion sequence, however.
[<i>Example:</i> a function with a ``<ins>lvalue-</ins>reference to
<tt>int</tt>'' parameter can be a viable candidate even if the corresponding
argument is an <tt>int</tt> bit-field. The formation of implicit conversion
sequences treats the <tt>int</tt> bit-field as an <tt>int</tt> lvalue and finds
an exact match with the parameter. If the function is selected by overload
resolution, the call will nonetheless be ill-formed because of the prohibition
on binding a non-const <ins>lvalue-</ins>reference to a bit-field
(dcl.init.ref). ]
</p>

<h2>13.3.3.2 Ranking implicit conversion sequences</h2>

<p>
-3- Two implicit conversion sequences of the same form are indistinguishable
conversion sequences unless one of the following rules apply:
</p>
<p>...</p>
<ul>
<li>
<tt>S1</tt> and <tt>S2</tt> differ only in their qualification conversion and
yield similar types <tt>T1</tt> and <tt>T2</tt> (conv.qual), respectively, and
the cv-qualification signature of type <tt>T1</tt> is a proper subset of the
cv-qualification signature of type <tt>T2</tt>, and <tt>S1</tt> is not the
deprecated string literal array-to-pointer conversion (conv.array).
[<i>Example:</i>
<blockquote><pre>
int f(const int *);
int f(int *);
int i;
int j = f(&amp;i);                  //  Calls  f(int   *)
</pre></blockquote>
--- end example] or, if not that,
</li>

<li><ins>
<tt>S1</tt> and <tt>S2</tt> are reference bindings (dcl.init.ref) and neither
refers to an implicit object parameter, and <tt>S1</tt> binds an
lvalue-reference to an lvalue and <tt>S2</tt> binds an rvalue-reference
or <tt>S1</tt> binds an rvalue-reference to an rvalue and <tt>S2</tt> binds an
lvalue-reference.<br> [<i>Example:</i>
</ins><blockquote><pre><ins>
int i;
int f();
int g(const int &amp;);
int g(const int &amp;&amp;);
int j = g(i);                  //  Calls  g(const int &amp;)
int k = g(f());                //  Calls  g(const int &amp;&amp;)

struct A {A&amp; operator&lt;&lt;(int);};
A&amp; operator&lt;&lt;(A&amp;&amp;, char);
A() &lt;&lt; 1;                      // Calls A::operator&lt;&lt;(int)
A() &lt;&lt; 'c';                    // Calls operator&lt;&lt;(A&amp;&amp;, char)
A a;
a &lt;&lt; 1;                        // Calls A::operator&lt;&lt;(int)
a &lt;&lt; 'c';                      // Calls operator&lt;&lt;(A&amp;&amp;, char)
</ins></pre></blockquote><ins>
--- <i>end example</i>] or, if not that,
</ins></li>
<li><tt>S1</tt> and <tt>S2</tt> are reference bindings...</li>
</ul>

<h2>14.3.1 - Template type arguments</h2>

<p>
-4- If a <i>template-argument</i> for a <i>template-parameter</i> <tt>T</tt>
names a type <del>``reference to <tt><i>cv1</i> S</tt>''</del> <ins>that is an
lvalue-reference or rvalue-reference to a type <tt>A</tt></ins>, an attempt to
create the type <del>``reference to <tt><i>cv2</i> T</tt>''</del> 
<ins>``lvalue-reference to <tt><i>cv</i> T</tt>''</ins> creates the type 
<del>``reference to <tt><i>cv12</i> S</tt>'', where <tt><i>cv12</i></tt> is the
union of the cv-qualifiers <tt><i>cv1</i></tt> and <tt><i>cv2</i></tt>. Redundant
cv-qualifiers are ignored</del> <ins>``lvalue-reference to <tt>A</tt>'', while
an attempt to create the type ``rvalue-reference to <tt><i>cv</i> T</tt>''
creates the type <tt>T</tt></ins>. [<i>Example:</i>
</p>

<blockquote><pre>
template &lt;class T&gt; class X {
    f(const T&amp;);
    <ins>g(T&amp;&amp;);</ins>
    /* ... */
};
X&lt;int&amp;&gt; x1;         // X&lt;int&amp;&gt;::f has the parameter type <del>const</del> int&amp;
<ins>                    // X&lt;int&amp;&gt;::g has the parameter type int&amp;
X&lt;const int&amp;&amp;&gt; x2;  // X&lt;const int&amp;&amp;&gt;::f has the parameter type const int&amp;
                    // X&lt;const int&amp;&amp;&gt;::g has the parameter type const int&amp;&amp;
</ins></pre></blockquote>
<p>--<i>end example</i>]</p>

<h2>14.8.2.1 - Deducing template arguments from a function call</h2>

<p>
-3- If <tt>P</tt> is a cv-qualified type, the top level cv-qualifiers of
<tt>P</tt>'s type are ignored for type deduction. If <tt>P</tt> is a reference
type, the type referred to by <tt>P</tt> is used for type deduction.
<ins>If <tt>P</tt> is an rvalue-reference type and the argument is an lvalue,
the type <tt>A&amp;</tt> is used in place of <tt>A</tt> for type deduction.
[<i>Example:</i></ins>
</p>

<blockquote><pre><ins>
template&lt;typename T&gt; int f(T&amp;&amp;);
int i;
int j = f(i);    // calls f&lt;int&amp;&gt;(i)
</ins></pre></blockquote>
<p><ins>
--- <i>end example</i>]
</ins></p>

<h2>14.8.2.5 - Deducing template arguments from a type</h2>

<p>
-8- A template type argument <tt>T</tt>, a template template argument <tt>TT</tt>
or a template non-type argument <tt>i</tt> can be deduced if <tt>P</tt> 
and <tt>A</tt> have one of the following forms:
</p>

<blockquote><pre>
T
<i>cv-list</i> T
T*
T&amp;
<ins>T&amp;&amp;</ins>
T[<i>integer-constant</i>]
...
</pre></blockquote>

<h2>Acknowledgments</h2>

<p>
Many thanks to William M. (Mike) Miller, Edison Design Group, Inc, for the
excellent review and suggestions.
</p>

</body>
</html>
