<html>
<head>
<title>Rvalue Reference Quick Look</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: N2027=06-0097<br>
<br>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br>
<a href="mailto:bs@cs.tamu.edu">Bjarne Stroustrup</a><br>
<a href="mailto:brok@rubikon.pl">Bronek Kozicki</a><br>

2006-06-12
</address>
<hr>
<h1 align=center>A Brief Introduction to Rvalue References</h1>

<h2>Abstract</h2>

<i>Rvalue references</i> is a small technical extension to the C++ language.
Rvalue references allow programmers to avoid logically unnecessary copying and
to provide perfect forwarding functions. They are primarily meant to aid in the
design of higer performance and more robust libraries.

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#rvalue_reference">The rvalue reference</a></li>
<li><a href="#Move_Semantics">Move Semantics</a></li>
<li><a href="#Perfect_Forwarding">Perfect Forwarding</a></li>
<li><a href="#Wrap_Up">References</a></li>
</ul>

<h2><a name="Introduction"></a>Introduction</h2>

<p>
This document gives a quick tour of the new C++ language feature
<i>rvalue reference</i>.  It is a brief tutorial, rather than a complete reference.
For details, see <a href="#Wrap_Up">these references</a>.
</p>

<h2><a name="rvalue_reference"></a>The rvalue reference</h2>

<p>
An <i>rvalue reference</i> is a compound type very similar to C++'s traditional reference.
To better distinguish these two types, we refer to a traditional C++ reference
as an <i>lvalue reference</i>.  When the term <i>reference</i> is used, it refers to
both kinds of reference: lvalue reference and rvalue reference.
</p>

<p>
An lvalue reference is formed by placing an <tt>&amp;</tt> after some type.
</p>

<blockquote><pre>
A a;
A&amp; a_ref1 = a;  <font color="#C80000">// an lvalue reference</font>
</pre></blockquote>

<p>
An rvalue reference is formed by placing an <tt>&amp;&amp;</tt> after some type.
</p>

<blockquote><pre>
A a;
A&amp;&amp; a_ref2 = a;  <font color="#C80000">// an rvalue reference</font>
</pre></blockquote>

<p>
An rvalue reference behaves just like an lvalue reference except that it <em>can</em> bind
to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an
rvalue.
</p>

<blockquote><pre>
A&amp;  a_ref3 = A();  <font color="#C80000">// Error!</font>
A&amp;&amp; a_ref4 = A();  <font color="#C80000">// Ok</font>
</pre></blockquote>

<p>
<i>Question:</i> Why on Earth would we want to do this?!
</p>

<p>
It turns out that the combination of rvalue references and lvalue references is
just what is needed to easily code <i>move semantics</i>.  The rvalue reference can
also be used to achieve <i>perfect forwarding</i>, a heretofore unsolved problem in
C++. From a casual programmer's perspective, what we get from rvalue references is more general and
better performing libraries.
</p>

<h2><a name="Move_Semantics"></a>Move Semantics</h2>

<h3>Eliminating spurious copies</h3>

Copying can be expensive.
For example, for <tt>std::vector</tt>s, <tt>v2=v1</tt> typically involves a function call,
a memory allocation, and a loop. This is of course acceptable where we actually need two
copies of a <tt>vector</tt>, but in many cases, we don't:
We often copy a <tt>vector</tt> from one place to another, just to proceed to overwrite the old copy.
Consider:

<blockquote><pre>
template &lt;class T&gt; swap(T&amp; a, T&amp; b)
{
    T tmp(a);   <font color="#C80000">// now we have two copies of a</font>
    a = b;      <font color="#C80000">// now we have two copies of b</font>
    b = tmp;    <font color="#C80000">// now we have two copies of tmp (aka a)</font>
}
</pre></blockquote>

But, we didn't want to have <i>any</i> copies of <tt>a</tt> or <tt>b</tt>,
we just wanted to swap them.
Let's try again:

<blockquote><pre>
template &lt;class T&gt; swap(T&amp; a, T&amp; b)
{
    T tmp(std::move(a));
    a = std::move(b);   
    b = std::move(tmp);
}
</pre></blockquote>

<p>
This <tt>move()</tt> gives its target the value of its argument, but is not obliged to
preserve the value of its source. So, for a <tt>vector</tt>, <tt>move()</tt> could
reasonably be expected to leave its argument as a zero-capacity <tt>vector</tt> to avoid having to
copy all the elements. In other words, <tt>move</tt> is a potentially destructive read.
</p>

<p>
In this particular case, we could have optimized <tt>swap</tt> by a specialization.
However, we can't specialize every function that copies a large object just before it
deletes or overwrites it. That would be unmanageable.
</p>

<p>
The first task of rvalue references is to allow us to implement <tt>move()</tt> without
verbosity, or rutime overhead.
</p>

<h3><tt>move</tt></h3>

<p>
The <tt>move</tt> function really does very little work.  All
<tt>move</tt> does is accept either an lvalue or rvalue argument, and return it
as an rvalue <em>without</em> triggering a copy construction:
</p>

<blockquote><pre>
template &lt;class T&gt;
typename remove_reference&lt;T&gt;::type&amp;&amp;
move(T&amp;&amp; a)
{
    return a;
}
</pre></blockquote>

<p>
It is now up to client code to overload key functions on whether their argument is
an lvalue or rvalue (e.g. copy constructor and assignment operator).  When the argument
is an lvalue, the argument must be copied from.  When it is an rvalue, it can safely
be moved from.
</p>

<h3>Overloading on lvalue / rvalue</h3>

<p>
Consider a simple <em>handle</em> class that owns a resource and also provides
copy semantics (copy constructor and assignment).  For example a <tt>clone_ptr</tt>
might own a pointer, and call <tt>clone()</tt> on it for copying purposes:
</p>

<blockquote><pre>
template &lt;class T&gt;
class clone_ptr
{
private:
    T* ptr;
public:
    <font color="#C87070">// construction</font>
    <font color="#707070">explicit clone_ptr(T* p = 0) : ptr(p) {}</font>

    <font color="#C87070">// destruction</font>
    <font color="#707070">~clone_ptr() {delete ptr;}</font>

    <font color="#C87070">// copy semantics</font>
    <font color="#707070">clone_ptr(const clone_ptr&amp; p)
        : ptr(p.ptr ? p.ptr-&gt;clone() : 0) {}

    clone_ptr&amp; operator=(const clone_ptr&amp; p)
    {
        if (this != &amp;p)
        {
            delete ptr;
            ptr = p.ptr ? p.ptr-&gt;clone() : 0;
        }
        return *this;
    }</font>

    <font color="#C80000">// move semantics</font>
    clone_ptr(clone_ptr&amp;&amp; p)
        : ptr(p.ptr) {p.ptr = 0;}

    clone_ptr&amp; operator=(clone_ptr&amp;&amp; p)
    {
        std::swap(ptr, p.ptr);
        return *this;
    }

    <font color="#C87070">// Other operations</font>
    <font color="#707070">T&amp; operator*() const {return *ptr;}
    // ...</font>
};
</pre></blockquote>

<p>
Except for the highlighted <i>move semantics</i> section above, <tt>clone_ptr</tt>
is code that you might find in today's books on C++.  Clients of <tt>clone_ptr</tt>
might use it like so:
</p>

<blockquote><pre>
clone_ptr&lt;base&gt; p1(new derived);
// ...
clone_ptr&lt;base&gt; p2 = p1;  <font color="#C80000">// p2 and p1 each own their own pointer</font>
</pre></blockquote>

<p>
Note that copy constructing or assigning a <tt>clone_ptr</tt> is a relatively expensive operation.
However when the source of the copy is known to be an rvalue, one can avoid the potentially
expensive <tt>clone()</tt> operation by pilfering the rvalue's pointer (no one will notice!).
The <i>move constructor</i> above does exactly that, leaving the rvalue in a default constructed
state.  The <i>move assignment</i> operator simply swaps state with the rvalue.
</p>

<p>
Now when code tries to copy an rvalue <tt>clone_ptr</tt>, or if that code explicitly gives
permission to consider the source of the copy an rvalue (using <tt>std::move</tt>), the
operation will execute <em>much</em> faster.
</p>

<blockquote><pre>
clone_ptr&lt;base&gt; p1(new derived);
// ...
clone_ptr&lt;base&gt; p2 = std::move(p1);  <font color="#C80000">// p2 now owns the pointer intead of p1</font>
</pre></blockquote>

<p>
For classes made up of other classes (via either containment or inheritance), the
move constructor and move assignment can easily be coded using the <tt>std::move</tt>
function:
</p>

<blockquote><pre>
class Derived
    : public Base
{
    std::vector&lt;int&gt; vec;
    std::string name;
    // ...
public:
    // ...
    <font color="#C80000">// move semantics</font>
    Derived(Derived&amp;&amp; x)              <font color="#C80000">// rvalues bind here</font>
        : Base(std::move(x)), 
          vec(std::move(x.vec)),
          name(std::move(x.name)) { }

    Derived&amp; operator=(Derived&amp;&amp; x)   <font color="#C80000">// rvalues bind here</font>
    {
        Base::operator=(std::move(x));
        vec  = std::move(x.vec);
        name = std::move(x.name);
        return *this;
    }
    // ...
};
</pre></blockquote>

<p>
Each subobject will now be treated as an rvalue when binding to the subobject's 
constructors and assignment operators.
<tt>std::vector</tt> and <tt>std::string</tt> have move operations coded (just like
our eariler <tt>clone_ptr</tt> example) which will completely avoid the tremendously
more expensive copy operations.
</p>

<p>
Note above that the argument <tt>x</tt> is treated
as an lvalue internal to the move functions, even though it is declared as an rvalue
reference parameter.  That's why it is necessary to say <tt>move(x)</tt> instead of
just <tt>x</tt> when passing down to the base class.  This is a key safety feature
of move semantics designed to prevent accidently moving twice from some named variable.
All moves occur only from rvalues, or with an explicit cast to rvalue such as using
<tt>std::move</tt>. <em>If you have a name for the variable, it is an lvalue.</em>
</p>

<p>
<i>Question:</i> What about types that don't own resources? (E.g. <tt>std::complex</tt>?)
</p>
<p>No work
needs to be done in that case.  The copy constructor is already optimal when copying
from rvalues.
</p>

<h3>Movable but Non-Copyable Types</h3>

<p>
Some types are not amenable to copy semantics but can still be made movable.  For example:
</p>

<ul>
<li><tt>fstream</tt></li>
<li><tt>unique_ptr</tt> (non-shared, non-copyable ownership)</li>
<li>A type representing a thread of execution</li>
</ul>

<p>
By making such types movable (though still non-copyable) their utility is tremendously
increased.  Movable but non-copyable types can be returned by value from factory functions:
</p>

<blockquote><pre>
ifstream find_and_open_data_file(/* ... */);
...
ifstream data_file = find_and_open_data_file(/* ... */);  <font color="#C80000">// No copies!</font>
</pre></blockquote>

<p>
In the above example, the underlying file handle is passed from object to object, as long
as the source <tt>ifstream</tt> is an rvalue.  At all times, there is still only one underlying
file handle, and only one <tt>ifstream</tt> owns it at a time.
</p>

<p>
Movable but non-copyable types can also safely be put into standard containers.  If the container
needs to "copy" an element internally (e.g. <tt>vector</tt> reallocation) it will move the
element instead of copy it.
</p>

<blockquote><pre>
vector&lt;unique_ptr&lt;base&gt;&gt; v1, v2;
v1.push_back(unique_ptr&lt;base&gt;(new derived()));  <font color="#C80000">// ok, moving, not copying</font>
...
v2 = v1;             <font color="#C80000">// Compile time error.  This is not a copyable type.</font>
v2 = move(v1);       <font color="#C80000">// Move ok.  Ownership of pointers transferred to v2.</font>
</pre></blockquote>

<p>
Many standard algorithms benefit from moving elements of the sequence as
opposed to copying them.  This not only provides better
performance (like the improved <tt>std::swap</tt> implementation described above),
but also allows these algorithms to operate on movable but non-copyable types.  For
example the following code sorts a <tt>vector&lt;unique_ptr&lt;T&gt;&gt;</tt> based
on comparing the pointed-to types:
</p>

<blockquote><pre>
struct indirect_less
{
    template &lt;class T&gt;
    bool operator()(const T&amp; x, const T&amp; y)
        {return *x &lt; *y;}
};
...
std::vector&lt;std::unique_ptr&lt;A&gt;&gt; v;
...
std::sort(v.begin(), v.end(), indirect_less());
</pre></blockquote>

<p>
As <tt>sort</tt> moves the <tt>unique_ptr</tt>'s around, it will use
<tt>swap</tt> (which no longer requires <tt>Copyability</tt>) or move
construction / move assignment.  Thus during the entire algorithm, the
invariant that each item is owned and referenced by one and only one smart pointer
is maintained.  If the algorithm were to attempt a copy (say by programming
mistake) a compile time error would result.
</p>

<h2><a name="Perfect_Forwarding"></a>Perfect Forwarding</h2>

<p>
Consider writing a generic factory function that returns a <tt>std::shared_ptr</tt> for a newly constructed
generic type. Factory functions such as
this are valuable for encapsulating and localizing the allocation of resources.
Obviously, the factory function must accept exactly the same sets of arguments as 
the constructors of the type of objects constructed.
Today this might be coded as:
</p>

<blockquote><pre>
template &lt;class T&gt;
std::shared_ptr&lt;T&gt;
factory()   <font color="#C80000">// no argument version</font>
{
    return std::shared_ptr&lt;T&gt;(new T);
}

template &lt;class T, class A1&gt;
std::shared_ptr&lt;T&gt;
factory(const A1&amp; a1)   <font color="#C80000">// one argument version</font>
{
    return std::shared_ptr&lt;T&gt;(new T(a1));
}

<font color="#C80000">// all the other versions</font>
</pre></blockquote>

<p>
In the interest of brevity, we will focus on just the one-parameter version. For example: 
</p>

<blockquote><pre>
std::shared_ptr&lt;A&gt; p = factory&lt;A&gt;(5);
</pre></blockquote>

<p>
<i>Question:</i> What if <tt>T</tt>'s constructor takes a parameter by non-const reference?
</p>
<p>
In that case, we get a compile-time error as the
const-qualifed argument of the <tt>factory</tt> function will not bind to the non-const
parameter of <tt>T</tt>'s constructor.
</p>

<p>
To solve that problem, we could use non-const parameters in our factory functions:
</p>

<blockquote><pre>
template &lt;class T, class A1&gt;
std::shared_ptr&lt;T&gt;
factory(A1&amp; a1)
{
    return std::shared_ptr&lt;T&gt;(new T(a1));
}
</pre></blockquote>

<p>
This is much better.  If a const-qualified type is passed to the <tt>factory</tt>, the
const will be deduced into the template parameter (<tt>A1</tt> for example) and then
properly forwarded to <tt>T</tt>'s constructor.  Similarly, if a non-const argument is given to
<tt>factory</tt>, it will be correctly forwarded to <tt>T</tt>'s constructor as a non-const.
Indeed, this is precisely how forwarding applications are coded today (e.g. <tt>std::bind</tt>).
</p>

<p>
However, consider:
</p>

<blockquote><pre>
std::shared_ptr&lt;A&gt; p = factory&lt;A&gt;(5);	<font color="#C80000">// error</font>
A* q = new A(5);	                <font color="#C80000">// ok</font>
</pre></blockquote>

<p>
This example worked with our first version of <tt>factory</tt>, but now it's broken:
The "<tt>5</tt>" causes the <tt>factory</tt> template argument to be deduced as <tt>int&amp;</tt>
and subsequently will not bind to the rvalue "<tt>5</tt>".  Neither solution so far is right.
Each breaks reasonable and common code.
</p>

<p>
<i>Question:</i> What about overloading on every combination of <tt>AI&amp;</tt> and
<tt>const AI&amp;</tt>?
</p>
<p>
This would allow us to handle all examples, but at a cost of an exponential explosion:
For our two-parameter case, this would require 4 overloads.
For a three-parameter <tt>factory</tt> we would need 8 additional overloads. 
For a four-parameter <tt>factory</tt> we would need 16, and so on. 
This is not a scalable solution.
</p>

<p>
Rvalue references offer a simple, scalable solution to this problem:
</p>

<blockquote><pre>
template &lt;class T, class A1&gt;
std::shared_ptr&lt;T&gt;
factory(A1&amp;&amp; a1)
{
    return std::shared_ptr&lt;T&gt;(new T(std::forward&lt;A1&gt;(a1)));
}
</pre></blockquote>

<p>
Now rvalue arguments can bind to the <tt>factory</tt> parameters.
If the argument is const,
that fact gets deduced into the <tt>factory</tt> template parameter type.
</p>

<p>
<i>Question:</i> What is that <tt>forward</tt> function in our solution?
</p>

<p>
Like <tt>move</tt>, <tt>forward</tt> is a simple standard library function used to
express our intent directly and explicitly, rather than through potentially cryptic
uses of references. We want to forward the argument <tt>a1</tt>, so we simply say so.
</p>

<p>
Here, <tt>forward</tt> preserves the lvalue/rvalue-ness of the argument that was passed to
<tt>factory</tt>.  If an rvalue is passed to <tt>factory</tt>, then an
rvalue will be passed to <tt>T</tt>'s constructor with the help of the <tt>forward</tt>
function.  Similarly, if an lvalue is passed to <tt>factory</tt>, it is forwarded to
<tt>T</tt>'s constructor as an lvalue.
</p>

<p>
The definition of <tt>forward</tt> looks like this:
</p>

<blockquote><pre>
template &lt;class T&gt;
struct identity
{
    typedef T type;
};

template &lt;class T&gt;
T&amp;&amp; forward(typename identity&lt;T&gt;::type&amp;&amp; a)
{
    return a;
}
</pre></blockquote>

<h2><a name="Wrap_Up"></a>References</h2>

<p>
As one of the main goals of this paper is brevity, there are details missing from the above
description.  But the above content represents 95% of the knowledge with a fraction of the
reading.
</p>

<p>
For further details on the motivation of move semantics, such as performance tests,
details of movable but non-copyable types, and many other details please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">N1377</a>.
</p>

<p>
For a very thorough treatment of the forwarding problem, please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</a>.
</p>

<p>
For further applications of the rvalue reference (besides move semantics
and perfect forwarding), please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">N1690</a>.
</p>

<p>
For proposed wording for the language changes required to standardize the
rvalue reference, please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1952.html">N1952</a>.
</p>

<p>
For a summary of the impact the rvalue reference will have on the standard
library, please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html">N1771</a>.
</p>

<p>
For proposed wording for the library changes required to take advantage of the
rvalue reference, please see:
</p>
<ul>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">N1856</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1857.html">N1857</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html">N1858</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1859.html">N1859</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1860.html">N1860</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1861.html">N1861</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1862.html">N1862</a></li>
</ul>

<p>
For a proposal to extend the rvalue reference to the implicit object parameter (<tt>this</tt>),
please see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm">N1821</a>.
</p>

</body>
</html>
