<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>A Safety Problem with RValue References (and what to do about it)</title>
<meta name="author" content="David Abrahams, Doug Gregor" />
<meta name="organization" content="BoostPro Computing, Apple" />
<meta name="date" content="2008-12-05" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 5631 2008-08-24 13:01:23Z goodger $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left {
  clear: left }

img.align-right {
  clear: right }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="a-safety-problem-with-rvalue-references-and-what-to-do-about-it">
<h1 class="title">A Safety Problem with RValue References (and what to do about it)</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>David Abrahams, Doug Gregor</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first reference external" href="mailto:dave&#64;boostpro.com">dave&#64;boostpro.com</a>, <a class="last reference external" href="mailto:doug.gregor&#64;gmail.com">doug.gregor&#64;gmail.com</a></td></tr>
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first reference external" href="http://www.boostpro.com">BoostPro Computing</a>, Apple</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2008-12-05</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">n2812=08-0322</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="index">
<p class="topic-title first">index</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id3">Introduction</a></li>
<li><a class="reference internal" href="#the-move-copy-overload-idiom" id="id4">The Move/Copy Overload Idiom</a><ul>
<li><a class="reference internal" href="#how-move-only-types-work" id="id5">How Move-Only Types Work</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-problem" id="id6">The Problem</a></li>
<li><a class="reference internal" href="#the-principle-at-stake" id="id7">The Principle at Stake</a></li>
<li><a class="reference internal" href="#proposed-solution" id="id8">Proposed Solution</a><ul>
<li><a class="reference internal" href="#impact-on-users" id="id9">Impact on Users</a></li>
<li><a class="reference internal" href="#impact-on-the-standard-library" id="id10">Impact on the Standard Library</a></li>
<li><a class="reference internal" href="#impact-on-implementations" id="id11">Impact on Implementations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#alternative-solutions" id="id12">Alternative Solutions</a><ul>
<li><a class="reference internal" href="#add-a-third-reference-type" id="id13">Add A Third Reference Type</a></li>
<li><a class="reference internal" href="#deleting-functions-that-fail-concept-constraints" id="id14">Deleting Functions that Fail Concept Constraints</a></li>
</ul>
</li>
<li><a class="reference internal" href="#acknowledgments" id="id15">Acknowledgments</a></li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id3">Introduction</a></h1>
<p>This paper describes a safety problem with rvalue references that can
cause unintentional modification of lvalues.  The underlying issue has
been known for some time, but recently-discovered examples have made
its seriousness much more apparent.  We also propose a solution to the
problem, which has been implemented in the GNU C++ compiler.</p>
<p>The example that made this safety problem with rvalue references
critical involves both rvalue references and concepts. The simplest
example is the conceptualized version of the <tt class="docutils literal"><span class="pre">push_back</span></tt> functions
in, e.g., <tt class="docutils literal"><span class="pre">std::list</span></tt>:</p>
<pre class="literal-block">
requires CopyConstructible&lt;value_type&gt;
void push_back(const value_type&amp; a);    // #1: copies a

requires MoveConstructible&lt;value_type&gt;
void push_back(value_type&amp;&amp; a);         // #2: moves from a
</pre>
<p>Recall that it's okay for #2 to modify its argument (by moving its
resources into the list) because changes to rvalues can't be observed
by other code. The safety problem here is that, if <tt class="docutils literal"><span class="pre">std::list</span></tt> is
instantiated with a movable but non-copyable type like <tt class="docutils literal"><span class="pre">std::unique_ptr&lt;int&gt;</span></tt>, one can
silently move from <em>lvalues</em>. For example:</p>
<pre class="literal-block">
void push_back2(
  std::list&lt;std::unique_ptr&lt;int&gt;&gt;&amp; l, std::unique_ptr&lt;int&gt; a)
{
  l.push_back(a); // oops: moves from the lvalue 'a', silently!
  l.push_back(a); // oops: 'a' no longer has its original value
}
</pre>
<p>The operation “move a value from <em>x</em>” is always safe when <em>x</em> is an
unnamed temporary.  Rvalue references were designed so that users must
<em>explicitly</em> write <tt class="docutils literal"><span class="pre">std::move(x)</span></tt> otherwise.  However, the example
above illustrates that the intended safety mechanism can disappear
without an explicit <tt class="docutils literal"><span class="pre">std::move</span></tt>.</p>
<p>What happened? When <tt class="docutils literal"><span class="pre">std::list</span></tt> is instantiated, the compiler eliminates any
declarations whose concept requirements cannot be satisfied.  Since
<tt class="docutils literal"><span class="pre">std::unique_ptr&lt;int&gt;</span></tt> does not satisfy <tt class="docutils literal"><span class="pre">CopyConstructible</span></tt> as
required by #1, the only <tt class="docutils literal"><span class="pre">push_back</span></tt> function that exists in
<tt class="docutils literal"><span class="pre">std::list&lt;std::unique_ptr&lt;int&gt;&gt;</span></tt> is:</p>
<pre class="literal-block">
void push_back(std::unique_ptr&lt;int&gt;&amp;&amp; a);                // #2: moves from a
</pre>
<p>The call <tt class="docutils literal"><span class="pre">l.push_back(x)</span></tt> succeeds because rvalue references bind
liberally to lvalues.  Then, <tt class="docutils literal"><span class="pre">push_back</span></tt> treats the lvalue as if it
were an rvalue, silently moving from it and destroying the value of
<tt class="docutils literal"><span class="pre">x</span></tt>.</p>
<p>Note that without concept requirements, two <tt class="docutils literal"><span class="pre">push_back</span></tt> overloads
are always available:</p>
<pre class="literal-block">
void push_back(const X&amp; a); // #1: copies a
void push_back(X&amp;&amp; a);      // #2: moves from a
</pre>
<p>With both overloads in play, the lvalue reference in #1 is a better
match for lvalue arguments than the rvalue reference in #2.
Instantiation of #1 finally fails only when it attempts to copy its
argument.</p>
</div>
<div class="section" id="the-move-copy-overload-idiom">
<h1><a class="toc-backref" href="#id4">The Move/Copy Overload Idiom</a></h1>
<p>To understand how we ended up silently moving from lvalues, let's
review the canonical implementation of move semantics. In C++03,
<tt class="docutils literal"><span class="pre">std::list</span></tt> only provides a single <tt class="docutils literal"><span class="pre">push_back</span></tt> operation:</p>
<pre class="literal-block">
void push_back(const value_type&amp; x); // #1
</pre>
<p>This operation copies the value <tt class="docutils literal"><span class="pre">x</span></tt> into the list.  If the value
provided for <tt class="docutils literal"><span class="pre">x</span></tt> is actually a temporary value that is expensive to
copy (say, a large string or a container of strings), copying <tt class="docutils literal"><span class="pre">x</span></tt> is
wasted effort: we're making an expensive copy of something that will be
destroyed anyway.</p>
<p>That's where move semantics come in. The idea is to <em>transfer
ownership</em> of <tt class="docutils literal"><span class="pre">x</span></tt>'s contents into the list instead of allocating new
memory and making a copy.  We can do that when the argument is a
temporary, e.g.,</p>
<pre class="literal-block">
std::list&lt;std::string&gt; l;
l.push_back(string(&quot;temporary&quot;));
</pre>
<p>because the string is an unnamed temporary and thus inaccessible and
invisible to the rest of the program.  If we steal from an
rvalue, nobody can know the difference: that's the key to move
semantics.</p>
<p>To add move semantics, we add a <tt class="docutils literal"><span class="pre">push_back</span></tt> overload version that
takes its second parameter by rvalue reference:</p>
<pre class="literal-block">
void push_back(value_type&amp;&amp; x); // #2
</pre>
<p>This idiom relies on the presence of <em>both</em> overloads.  Overload #2
makes it move, but overload #1 makes it safe by attracting lvalues.
Without overload #1, <tt class="docutils literal"><span class="pre">push_back</span></tt> will move from lvalues, silently
turning a logically non-mutating operation into a mutating one.</p>
<div class="section" id="how-move-only-types-work">
<h2><a class="toc-backref" href="#id5">How Move-Only Types Work</a></h2>
<p>A movable-but-noncopyable <tt class="docutils literal"><span class="pre">value_type</span></tt> follows the same binding
pattern as any other <tt class="docutils literal"><span class="pre">value_type</span></tt>: rvalue arguments, which can be
safely moved from, always select overload #2:</p>
<pre class="literal-block">
std::list&lt;std::unique_ptr&lt;int&gt;&gt; l;
l.push_back(std::unique_ptr&lt;int&gt;(new int));
</pre>
<p>As before, lvalue arguments select overload #1:</p>
<pre class="literal-block">
void f(std::list&lt;std::unique_ptr&lt;int&gt;&gt; l, std::unique_ptr&lt;int&gt; p) {
  l.push_back(p); // calls #1
}
</pre>
<p>However, since the argument type is noncopyable, the body of #1 fails
compilation (as desired) when it attempts to make a copy of the
<tt class="docutils literal"><span class="pre">unique_ptr</span></tt>.</p>
</div>
</div>
<div class="section" id="the-problem">
<h1><a class="toc-backref" href="#id6">The Problem</a></h1>
<p>The problem with the formulation of the move/copy idiom is that the
lvalue/rvalue overload set doesn't degrade safely.  If overload #1 is
removed from consideration, overload #2 will match both rvalues and
lvalues, moving silently from all mutable arguments.</p>
<p>There are a number of possible reasons for such a removal, but simple
programmer blunders may be the most likely causes.  For example, an errant
finger might hit the delete key when overload #1 is selected.  Some
mistakes are not nearly so obvious, because overloads can be removed
due to template argument deduction failure (SFINAE) <a class="footnote-reference" href="#sfinae" id="id2">[1]</a> or
because certain concept requirements are not satisfied.</p>
<p>For example, consider an &quot;enqueue&quot; function that either copies or
moves the elements from a source queue into a destination queue, using
the typical copy/move idiom:</p>
<pre class="literal-block">
template &lt;class T, typename Cont&gt;
void enqueue(queue&lt;T, Cont&gt;&amp; dest, const queue&lt;T, Cont&gt;&amp; src) // #3a

template &lt;class T, typename Cont&gt;
void enqueue(queue&lt;T, Cont&gt;&amp; dest, queue&lt;T, Cont&gt;&amp;&amp; src); // #4
</pre>
<p>Now, in the case where we're copying from one queue to another, it
might make sense to provide an optional allocator, so we replace #3a
with:</p>
<pre class="literal-block">
template &lt;class T, typename Cont&gt;
void enqueue(
  queue&lt;T, Cont&gt;&amp; dest, const queue&lt;T, Cont&gt;&amp; src,
  typename Cont::allocator_type alloc = typename Cont::allocator_type()); // #3b
</pre>
<p>This overload set will move from rvalues and copy from lvalues in most
common cases, e.g.,</p>
<pre class="literal-block">
queue&lt;string, list&lt;string&gt;&gt; dest;
queue&lt;string, list&lt;string&gt;&gt; src;
enqueue(dest, src); // okay, calls #3b to copy from src into dest
enqueue(dest, queue&lt;string, list&lt;string&gt;&gt;()); // okay, calls #4 to move from src to dest
</pre>
<p>However, not all container types <tt class="docutils literal"><span class="pre">Cont</span></tt> have allocators, and we can
run into trouble again:</p>
<pre class="literal-block">
class simple_list {
  // ... no allocator_type ...
};

queue&lt;string, simple_list&lt;string&gt;&gt; dest;
queue&lt;string, simple_list&lt;string&gt;&gt; src;
enqueue(dest, src); // oops: calls #4, silently moving from the lvalue 'src'
</pre>
<p>What happened here is similar to what happened with the conceptualized
verison of <tt class="docutils literal"><span class="pre">push_back</span></tt>, but this time concepts are not involved. In
this case, template argument
deduction for the call to #3b deduces <tt class="docutils literal"><span class="pre">T=string</span></tt> and
<tt class="docutils literal"><span class="pre">Cont=simple_list&lt;string&gt;</span></tt>. Then, while substituting those deduced
template arguments into the signature of #3b, we attempt to look up the
type <tt class="docutils literal"><span class="pre">simple_list&lt;string&gt;::allocator_type</span></tt>, which does not
exist. This is a SFINAE case, so #3b is removed from consideration and
the overload set only contains #4. The rvalue reference parameter of
#4 binds to the lvalue <tt class="docutils literal"><span class="pre">src</span></tt>, and we silently move from an lvalue.</p>
</div>
<div class="section" id="the-principle-at-stake">
<h1><a class="toc-backref" href="#id7">The Principle at Stake</a></h1>
<p>Fundamentally, the problem we've described occurs because the rvalue
reference binding rules violate an important principle of type safety:</p>
<div class="admonition-principle-of-type-safe-overloading-pto admonition">
<p class="first admonition-title">Principle of Type-safe Overloading (PTO)</p>
<p class="last">Every function must be type-safe in isolation, <em>without regard to
how it has been overloaded.</em></p>
</div>
<p>This violation of principle manifests itself in several ways:</p>
<p>From an author's point-of-view, we have been forced <em>add</em> a new
overload to <em>remove</em> unwanted behavior.</p>
<p>From a client's point-of-view, under the current rules, a function
that accepts an rvalue reference does not crisply state its contract
in the type system:</p>
<pre class="literal-block">
void f(X&amp;&amp;);
</pre>
<p>From looking at <tt class="docutils literal"><span class="pre">f</span></tt>, is not clear whether it is</p>
<ol class="loweralpha simple">
<li>meant to mutate rvalues <em>and lvalues</em>, or</li>
<li>responsible for moving from rvalues as part of a
logically-non-mutating overload set</li>
</ol>
<p>The contract can be expressed as documentation, but to put it in code
may require the addition of a second <tt class="docutils literal"><span class="pre">f</span></tt> overload, e.g.,</p>
<pre class="literal-block">
void f(value_type const&amp;) = delete;
</pre>
<p>to ban the use of lvalues.  Taken to its logical extreme, a client may
need to see <em>all</em> the code in the translation unit in order to know
whether this function is capable of mutating its argument.  There is
no precedent in const-correct code for such a dispersal of semantic
information, or for a non-mutating call to become mutating when an
overload is removed from the set.</p>
<p>So why is this happening now?  Before we had rvalue references, it was
easy to adhere to the PTO without giving it any special attention.
Move semantics, however, introduce a special case: we need to <em>modify</em>
an rvalue argument as part of a <em>logically non-mutating</em> operation.
This paradox is only possible because of a special property of
rvalues: that they can be modified with assurance that the
modification can't be observed.</p>
</div>
<div class="section" id="proposed-solution">
<h1><a class="toc-backref" href="#id8">Proposed Solution</a></h1>
<p>We propose to prohibit rvalue references from binding to
lvalues. Therefore, an rvalue reference will always refer to an rvalue
or to an lvalue that the user has explicitly transformed into an
rvalue (e.g., through the use of <tt class="docutils literal"><span class="pre">std::move</span></tt>). This makes the
overload sets used in the copy/move idiom degrade safely when either
of the overloads is removed for any reason. For example, with this
change, given just a single function template <tt class="docutils literal"><span class="pre">enqueue</span></tt>:</p>
<pre class="literal-block">
template &lt;class T, typename Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, queue&lt;T, Cont&gt;&amp;&amp; src); // #4
</pre>
<p>calling <tt class="docutils literal"><span class="pre">enqueue</span></tt> with an rvalue succeeds while calling it with an
lvalue fails:</p>
<pre class="literal-block">
queue&lt;string, list&lt;string&gt;&gt; dest;
queue&lt;string, list&lt;string&gt;&gt; src;
enqueue(dest, src); // error: cannot bind rvalue reference in #4 to lvalue 'src'
enqueue(dest, queue&lt;string, list&lt;string&gt;&gt;()); // okay, calls #4 to move from temporary to dest
</pre>
<p>We can then add back the previously-problematic overload that allows
one to copy from the source queue while enqueing its elements, and
provide an allocator:</p>
<pre class="literal-block">
template &lt;class T, typename Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, const queue&lt;T, Cont&gt;&amp; src,
               typename Cont::allocator_type alloc = typename Cont::allocator_type()); // #3b
</pre>
<p>Now, if we attempt to enqueue elements from an lvalue where the
queue's container does not have an allocator, we receive an error
message stating that no <tt class="docutils literal"><span class="pre">enqueue</span></tt> function can be called, rather than
silently moving from lvalue:</p>
<pre class="literal-block">
queue&lt;string, simple_list&lt;string&gt;&gt; dest;
queue&lt;string, simple_list&lt;string&gt;&gt; src;
enqueue(dest, src); // error: #3b fails template argument deduction
                    //        #4  cannot be called because src isn't an lvalue
</pre>
<p>Our proposed solution retains the behavior of the copy/move idiom
while still adhering to the principle of type-safe overloading and
eliminating the safety hole that allowed silently moves from lvalues.</p>
<div class="section" id="impact-on-users">
<h2><a class="toc-backref" href="#id9">Impact on Users</a></h2>
<p>The most important aspect of this solution is that it does not change
the common idioms that employ rvalue references. For example,
when we want to optimize for rvalues (e.g., by implementing move
semantics), we still implement two overloads: one with an lvalue
reference to const and one with an rvalue reference, e.g.,:</p>
<pre class="literal-block">
void push_back(const value_type&amp; x); // copies x
void push_back(value_type&amp;&amp; x); // moves x
</pre>
<p>With the proposed change, the introduction of concepts into these
functions does not result in any surprises:</p>
<pre class="literal-block">
requires CopyConstructible&lt;value_type&gt;
  void push_back(const value_type&amp; x); // copies x
requires MoveConstructible&lt;value_type&gt;
  void push_back(value_type&amp;&amp; x); // moves x
</pre>
<p>For a move-only type <tt class="docutils literal"><span class="pre">X</span></tt>, the first <tt class="docutils literal"><span class="pre">push_back</span></tt> will be eliminated
because template argument deduction fails (<tt class="docutils literal"><span class="pre">X</span></tt> does not meet the
<tt class="docutils literal"><span class="pre">CopyConstructible</span></tt> requirements), and the second <tt class="docutils literal"><span class="pre">push_back</span></tt>
only accepts rvalues. Hence, calling <tt class="docutils literal"><span class="pre">push_back</span></tt> with an lvalue of
move-only type <tt class="docutils literal"><span class="pre">X</span></tt> will result in an error.</p>
<p>The proposed change also does not have any impact on the use
of rvalue references for perfect forwarding, e.g.,:</p>
<pre class="literal-block">
template &lt;class F, class T&gt;
void thunk(F f, T&amp;&amp; x) { f(std::forward&lt;T&gt;(x)); }
</pre>
<p>When an lvalue of type <tt class="docutils literal"><span class="pre">U</span></tt> is passed to <tt class="docutils literal"><span class="pre">f</span></tt>, the special template
argument deduction rules for <tt class="docutils literal"><span class="pre">T&amp;&amp;</span></tt> ensure that <tt class="docutils literal"><span class="pre">T</span></tt> is deduced as
<tt class="docutils literal"><span class="pre">U&amp;</span></tt>. Then, when substituting <tt class="docutils literal"><span class="pre">T=U&amp;</span></tt> into <tt class="docutils literal"><span class="pre">T&amp;&amp;</span></tt>, reference
collapsing transforms the resulting argument type to <tt class="docutils literal"><span class="pre">U&amp;</span></tt>, an lvalue
reference that is able to bind to the lvalue argument of type
<tt class="docutils literal"><span class="pre">U</span></tt>. Hence, lvalues bind to lvalue references and rvalues bind to
rvalue references.</p>
<p>The only user code that will be directly affected by the proposed
change is when a function performs the same operation regardless of
whether it receives an lvalue or an rvalue. For example, this approach
has been used with member <tt class="docutils literal"><span class="pre">swap</span></tt> to permit swapping with rvalues, e.g.,:</p>
<pre class="literal-block">
struct mytype {
  void swap(mytype&amp;&amp; other); // other can be an lvalue or rvalue
};

void f(mytype&amp; m1, mytype&amp; m2) {
  m.swap(mytype()); // okay: rvalue reference binds to rvalues
  m1.swap(m2); // okay under the existing rules, ill-formed with the proposed rules
}
</pre>
<p>With the proposed change, the definition of <tt class="docutils literal"><span class="pre">mytype</span></tt> would have to be
extended to include two <tt class="docutils literal"><span class="pre">swap</span></tt> overloads, one for lvalues and one for
rvalues. The rvalue-reference version would merely forward to the
lvalue-reference version, e.g.,:</p>
<pre class="literal-block">
struct mytype {
  void swap(mytype&amp; other);
  void swap(mytype&amp;&amp; other) { swap(other); } // 'other' is treated as an lvalue
};
</pre>
<p>Since the vast majority of uses of rvalue references fall into one of
the first two idioms---paired overloads for move semantics and the use
of <tt class="docutils literal"><span class="pre">std::forward</span></tt> for perfect forwarding---and the workaround for the
few functions like <tt class="docutils literal"><span class="pre">swap</span></tt> that depend on the current behavior is very
simple, we do not expect any significant impact on user code. On the
other hand, the proposed change eliminates a particularly vexing
problem with rvalue references that makes them almost unusable with
concepts and somewhat dangerous even without concepts.</p>
</div>
<div class="section" id="impact-on-the-standard-library">
<h2><a class="toc-backref" href="#id10">Impact on the Standard Library</a></h2>
<p>The change in the binding of rvalue references affects the standard
library in four different areas: the definitions of <tt class="docutils literal"><span class="pre">std::move</span></tt> and
<tt class="docutils literal"><span class="pre">std::forward</span></tt>, the definition of member <tt class="docutils literal"><span class="pre">swap</span></tt>, the formulation
of the stream insertion/extraction operators, and the description of
the <tt class="docutils literal"><span class="pre">Iterator</span></tt> concept.</p>
<p>Both <tt class="docutils literal"><span class="pre">std::move</span></tt> and <tt class="docutils literal"><span class="pre">std::forward</span></tt> rely on the ability of an
rvalue reference to bind to an lvalue. For <tt class="docutils literal"><span class="pre">std::move</span></tt>, this binding
is used to return the argument <tt class="docutils literal"><span class="pre">x</span></tt> (which is always treated as an
lvalue) from the function:</p>
<pre class="literal-block">
template&lt;typename T&gt;
  inline typename std::remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp; x)
  { return x; }
</pre>
<p>With our proposed change, a new formulation of <tt class="docutils literal"><span class="pre">std::move</span></tt> is
required. It explicitly casts the lvalue to an rvalue reference type
(making it an rvalue), which can bind to the rvalue-reference result
type:</p>
<pre class="literal-block">
template&lt;typename T&gt;
  inline typename std::remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp; x)
  { return static_cast&lt;typename std::remove_reference&lt;T&gt;::type&amp;&amp;&gt;(x); }
</pre>
<p><tt class="docutils literal"><span class="pre">std::forward</span></tt> relies on the binding of lvalues to rvalue references
in its argument type, since it is typically invoked with lvalues:</p>
<pre class="literal-block">
template&lt;typename T&gt;
  inline T&amp;&amp; forward(typename std::identity&lt;T&gt;::type&amp;&amp; x)
  { return x; }
</pre>
<p>With our proposed change to the binding rules for rvalue references,
we need make two changes. First, we add a second, lvalue-reference
overload of <tt class="docutils literal"><span class="pre">std::forward</span></tt> (that forwards lvalues as lvalues):</p>
<pre class="literal-block">
template&lt;typename T&gt;
  inline T&amp; forward(typename std::identity&lt;T&gt;::type&amp; x)
  { return x; }
</pre>
<p>Second, we need to make sure that the two definitions of
<tt class="docutils literal"><span class="pre">std::forward</span></tt> never produce identical function types, by banning
the original <tt class="docutils literal"><span class="pre">std::forward</span></tt> from being instantiated with lvalue
references:</p>
<pre class="literal-block">
template&lt;typename T&gt;
  inline typename disable_if&lt;is_lvalue_reference&lt;T&gt;, T&amp;&amp;&gt;::type
  forward(typename std::identity&lt;T&gt;::type&amp;&amp; x)
  { return static_cast&lt;T&amp;&amp;&gt;(x); }
</pre>
<p>Note that, with these changes to both <tt class="docutils literal"><span class="pre">std::move</span></tt> and
<tt class="docutils literal"><span class="pre">std::forward</span></tt>, the idiomatic uses of these functions still work, so
that user code will not need to change. Only the definitions of
<tt class="docutils literal"><span class="pre">std::move</span></tt> and <tt class="docutils literal"><span class="pre">std::forward</span></tt> are affected.</p>
<p>Each of the member <tt class="docutils literal"><span class="pre">swap</span></tt> functions in the standard library is
described in terms of rvalue references, e.g.,:</p>
<pre class="literal-block">
void swap(vector&lt;T,Alloc&gt;&amp;&amp;);
</pre>
<p>With our proposed change, these <tt class="docutils literal"><span class="pre">swap</span></tt> functions will no longer
accept lvalues, which would break a significant amount of
code. Therefore, we will need to introduce overloads of the member
<tt class="docutils literal"><span class="pre">swap</span></tt> functions that accept lvalues:</p>
<pre class="literal-block">
void swap(vector&lt;T,Alloc&gt;&amp;);
</pre>
<p>In fact, due to library issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#884">884</a>, it is possible that we will want
to eliminate the rvalue-reference versions of member <tt class="docutils literal"><span class="pre">swap</span></tt>
entirely.</p>
<p>With the introduction of rvalue references into the standard
library, the stream insertion and extraction operators were changed to
accept both lvalue and rvalue streams, e.g.,:</p>
<pre class="literal-block">
template&lt;class charT, class traits, class Allocator&gt;
  basic_ostream&lt;charT, traits&gt;&amp;
  operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp;&amp; os, const basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre>
<p>This change made it possible to create a temporary stream and use it
within one expression, e.g.,:</p>
<pre class="literal-block">
std::ofstream(&quot;out.txt&quot;) &lt;&lt; &quot;Hello!&quot;; // ill-formed in C++03, okay in C++0x
</pre>
<p>With our proposed change to rvalue references, each of the stream
insertion and extraction operators will need to use an lvalue
reference to their stream argument to bind to lvalue streams,
effectively reverting streams to their C++03 behavior:</p>
<pre class="literal-block">
template&lt;class charT, class traits, class Allocator&gt;
  basic_ostream&lt;charT, traits&gt;&amp;
  operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const basic_string&lt;charT,traits,Allocator&gt;&amp; str);
</pre>
<p>If we determine that the use case above for temporary streams is
important, we could extend the library with the following two function
templates:</p>
<pre class="literal-block">
template&lt;typename _CharT, typename _Traits, typename _Tp&gt;
inline basic_ostream&lt;_CharT, _Traits&gt;&amp;
operator&lt;&lt;(basic_ostream&lt;_CharT, _Traits&gt;&amp;&amp; __stream, const _Tp&amp; __x)
{
  __stream &lt;&lt; __x;
  return __stream;
}

// Input via an rvalue stream
template&lt;typename _CharT, typename _Traits, typename _Tp&gt;
inline basic_istream&lt;_CharT, _Traits&gt;&amp;
operator&gt;&gt;(basic_istream&lt;_CharT, _Traits&gt;&amp;&amp; __stream, _Tp&amp; __x)
{
  __stream &gt;&gt; __x;
  return __stream;
}
</pre>
<p>These templates allow stream insertion and extraction with an rvalue
stream, forwarding the stream as an lvalue to use whatever stream
insertion/extraction operator already exists. Thus, we still support
the use of rvalue streams throughout the library, and use cases like
the following will work in C++0x:</p>
<pre class="literal-block">
std::ofstream(&quot;out.txt&quot;) &lt;&lt; &quot;Hello!&quot;; // okay: uses rvalue-stream template above
</pre>
<p>Finally, the current definition of the <tt class="docutils literal"><span class="pre">Iterator</span></tt> concept has a
dereference operator that uses rvalue references to accept both
lvalue and rvalue iterators:</p>
<pre class="literal-block">
reference operator*(Iter&amp;&amp;);
</pre>
<p>We will need to augment the <tt class="docutils literal"><span class="pre">Iterator</span></tt> concept with a second
overload of <tt class="docutils literal"><span class="pre">operator*</span></tt>:</p>
<pre class="literal-block">
reference operator*(Iter&amp;);
</pre>
<p>Note that we use a non-const lvalue reference for this overload,
because it is common with output iterators to deference non-const
iterator lvalues (and the dereference operators often return non-const
references to the same type).</p>
<p>Overall, despite the fact that our proposed change to the binding of
rvalue references will affect several different parts of the library,
we are able to maintain the same user experience through the
introduction of additional overloads and a different implementation of
<tt class="docutils literal"><span class="pre">std::move</span></tt>/<tt class="docutils literal"><span class="pre">std::forward</span></tt>. Thus, our proposed change improves the
safety of the library and of user code while maintaining backward
compatibility with C++03 and with the new features added into C++0x.</p>
</div>
<div class="section" id="impact-on-implementations">
<h2><a class="toc-backref" href="#id11">Impact on Implementations</a></h2>
<p>We have produced an implementation of the proposed solution in the GNU
C++ compiler, which is available as a <a class="reference external" href="http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00436.html">patch</a> against GCC 4.3.2. The
actual implementation of the language change is trivial---we merely
check whether the binding computed would bind an lvalue to an rvalue
reference, and reject the binding in this case. The changes to the
standard library are slightly more involved, because we needed to
implement the changes described in the section <a class="reference internal" href="#impact-on-the-standard-library">Impact on the Standard
Library</a>. We do not anticipate that this change will have any
significant impact on compilers or standard library
implementations. The GCC implementation required a day's effort to
update both the language and the library, although more effort would
certainly be required to update the test cases associated with this
feature.</p>
</div>
</div>
<div class="section" id="alternative-solutions">
<h1><a class="toc-backref" href="#id12">Alternative Solutions</a></h1>
<p>Two alternatives to our proposed solution have been proposed. One
alternative is actually an extension to the proposed solution, which
adds a third kind of reference type; the other modifies the behavior
of concepts to preserve more of the overloading behavior of
unconstrained templates. Although we describe these two alternatives
here, we do not propose either of them.</p>
<div class="section" id="add-a-third-reference-type">
<h2><a class="toc-backref" href="#id13">Add A Third Reference Type</a></h2>
<p>With the removal of the binding from rvalue references to lvalues,
certain functions that work equally well on both lvalues and
rvalues---such as <tt class="docutils literal"><span class="pre">swap</span></tt> or the stream insertion/extraction
operators---will need to provide additional overloads, e.g.,:</p>
<pre class="literal-block">
void swap(mytype&amp;&amp;);
</pre>
<p>becomes:</p>
<pre class="literal-block">
void swap(mytype&amp;);
void swap(mytype&amp;&amp; other) { swap(other); }
</pre>
<p>If there were multiple parameters that could be either lvalues or
rvalues, the number of required overloads would grow exponentially. For
example, a non-member <tt class="docutils literal"><span class="pre">swap</span></tt> that supports all combinations of lvalues
and rvalues would go from:</p>
<pre class="literal-block">
void swap(mytype&amp;&amp;, mytype&amp;&amp;);
</pre>
<p>to:</p>
<pre class="literal-block">
void swap(mytype&amp;, mytype&amp;);
void swap(mytype&amp;  x, mytype&amp;&amp; y) { swap(x, y); }
void swap(mytype&amp;&amp; x, mytype&amp;  y) { swap(x, y); }
void swap(mytype&amp;&amp; x, mytype&amp;&amp; y) { swap(x, y); }
</pre>
<p>At this point, we know of no use cases that would involve more than
two parameters that can either be lvalues or rvalues, other than those
that are actually versions of perfect forwarding (and which are,
therefore, not affected by the proposed change). Nonetheless, to
address this issue, one could extend our proposed resolution to
support a third kind of reference (spelled <tt class="docutils literal"><span class="pre">&amp;&amp;&amp;</span></tt>) that binds to
either lvalues or rvalues, effectively providing the current behavior
of <tt class="docutils literal"><span class="pre">&amp;&amp;</span></tt> but with a new spelling. Thus, the above swap could be written
as:</p>
<pre class="literal-block">
void swap(mytype&amp;&amp;&amp;, mytype&amp;&amp;&amp;);
</pre>
<p>Interestingly, the current working paper's definition of non-member
<tt class="docutils literal"><span class="pre">swap</span></tt> would not benefit from the addition of <tt class="docutils literal"><span class="pre">&amp;&amp;&amp;</span></tt>. The working
paper provides three overloads of each non-member swap, prohibiting
rvalue-rvalue swaps:</p>
<pre class="literal-block">
void swap(mytype&amp; , mytype&amp;);
void swap(mytype&amp;&amp;, mytype&amp;);
void swap(mytype&amp; , mytype&amp;&amp;);
</pre>
<p>This overload set works the same way regardless of whether rvalue
references bind to lvalues. Moreover, an LWG straw poll in San
Francisco voted to revert from using three non-member swaps back to
having only a single, lvalue-lvalue swap:</p>
<pre class="literal-block">
void swap(mytype&amp;, mytype&amp;);
</pre>
<p>due to library issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#884">884</a>. Thus, <tt class="docutils literal"><span class="pre">&amp;&amp;&amp;</span></tt> is not likely to be used in the
working paper for non-member <tt class="docutils literal"><span class="pre">swap</span></tt>. For member <tt class="docutils literal"><span class="pre">swap</span></tt>, the number of
extra overloads (one per existing <tt class="docutils literal"><span class="pre">swap</span></tt>) required is not sufficient to
motivate the addition of another kind of reference.</p>
<p>With the stream insertion and extraction operators, the introduction
of the <tt class="docutils literal"><span class="pre">operator&gt;&gt;</span></tt> and <tt class="docutils literal"><span class="pre">operator&gt;&gt;</span></tt> templates described in
section <a class="reference internal" href="#impact-on-the-standard-library">Impact on the Standard Library</a> eliminates the need for the
use of <tt class="docutils literal"><span class="pre">&amp;&amp;&amp;</span></tt>. We expect that most other uses of <tt class="docutils literal"><span class="pre">&amp;&amp;&amp;</span></tt> can be
addressed using this approach.</p>
</div>
<div class="section" id="deleting-functions-that-fail-concept-constraints">
<h2><a class="toc-backref" href="#id14">Deleting Functions that Fail Concept Constraints</a></h2>
<p>Another alternative solution that has been proposed to address the
problem posed by the conceptualized version of <tt class="docutils literal"><span class="pre">push_back</span></tt> is to
delete functions that fail to meet their concept requirements. That
way, these functions remain in the overload set but any attempt to use
them will result in an error. Recall the <tt class="docutils literal"><span class="pre">push_back</span></tt> overloads and
their concept constraints:</p>
<pre class="literal-block">
requires CopyConstructible&lt;value_type&gt;
  void push_back(const value_type&amp; x); // copies x
requires MoveConstructible&lt;value_type&gt;
  void push_back(value_type&amp;&amp; x); // moves x
</pre>
<p>When instantiated with a move-only type <tt class="docutils literal"><span class="pre">X</span></tt> for <tt class="docutils literal"><span class="pre">value_type</span></tt>, the
proposed solution would result in the following two functions:</p>
<pre class="literal-block">
void push_back(const X&amp; x) = delete; // X isn't CopyConstructible
void push_back(X&amp;&amp; x); // okay: X is MoveConstructible
</pre>
<p>This approach solves the problem for this example, because lvalues
passed to <tt class="docutils literal"><span class="pre">push_back</span></tt> will still be attracted to the lvalue
reference, and the compiler will produce a suitable error rather than
silently moving from an lvalue.</p>
<p>The main problem with this approach is that it only solves the problem
in those cases where the concept requirements of a template are not
satisfied but SFINAE does not eliminate the template from
consideration. For example, it does not solve the problem with the
<tt class="docutils literal"><span class="pre">enqueue</span></tt> function described above (which doesn't involve concepts):</p>
<pre class="literal-block">
template &lt;class T, typename Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, queue&lt;T, Cont&gt;&amp;&amp; src); // #1
template &lt;class T, typename Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, const queue&lt;T, Cont&gt;&amp; src,
               typename Cont::allocator_type alloc = typename Cont::allocator_type()); // #2
</pre>
<p>It also does not solve the problem with a conceptualized version of
the <tt class="docutils literal"><span class="pre">enqueue</span></tt> function:</p>
<pre class="literal-block">
template &lt;class T, Container Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, queue&lt;T, Cont&gt;&amp;&amp; src); // #1
template &lt;class T, ContainerWithAllocator Cont&gt;
  void enqueue(queue&lt;T, Cont&gt;&amp; dest, const queue&lt;T, Cont&gt;&amp; src,
               Cont::allocator_type alloc = Cont::allocator_type()); // #2
</pre>
<p>The conceptualized formulation of <tt class="docutils literal"><span class="pre">enqueue</span></tt> suffers from the same
problem as the pre-concepts version: since <tt class="docutils literal"><span class="pre">Cont</span></tt> is not a
<tt class="docutils literal"><span class="pre">ContainerWithAllocator</span></tt>, we cannot form the signature of the
deleted <tt class="docutils literal"><span class="pre">enqueue</span></tt> function, so only function #1 will enter the
overload set.  Since it is the only function available, it will move
from lvalues. Thus, the proposal to replace functions that fail their
concept requirements with deleted functions does not solve the general
problem, either with or without concepts.</p>
</div>
</div>
<div class="section" id="acknowledgments">
<h1><a class="toc-backref" href="#id15">Acknowledgments</a></h1>
<p>The authors thank Peter Dimov, Howard Hinnant, Jaakko Jarvi, Mat Marcus, and
Thomas Witt for many lively discussions on the topic of rvalue
references and concepts, where many of the ideas in this paper
originated.</p>
<hr class="docutils" />
<table class="docutils footnote" frame="void" id="sfinae" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>“Substitution Failure Is Not An Error.”  See Josuttis &amp;
Vandevoorde, <em>C++ Templates</em>.</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
