<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>forward</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 {color:#00A000}
	del {color:#A00000}
	</style>

</head>

<body>

<address align=right>
Document number: N2835=09-0025<br/>
<br>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br>
2009-03-22
</address>
<hr/>

<h1 align=center><tt>forward</tt></h1>

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#forward"><tt>forward</tt> Revealed</a></li>
<li><a href="#example">Example</a></li>
<li><a href="#proposed">Proposed Wording</a></li>
<li><a href="#Acknowledgements">Acknowledgements</a></li>
</ul>

<h2><a name="Introduction"></a>Introduction</h2>
<hr/>
<p>
<b>Update:</b>  This paper was written prior to the Summit meeting, but missed the
pre-meeting mailing deadline.  In Summit we accepted a minor revision of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html">N2831</a>
"Fixing a Safety Problem with Rvalue References: Proposed Wording", <em>except</em>
for the clause refering to <tt>forward</tt>.  I did not have time to update this
paper any more than this prior to the post Summit mailing.  I still
believe that the fundamental point of this paper is sound:
</p>

<blockquote>
It is both safe and useful to forward rvalues as rvalues (rows 7 and 8).
</blockquote>

<p>
In Summit we discussed constraining <tt>forward</tt> to disallow all conversions
except for adding cv-qualifiers, and except for the change in lvalue/rvalue-ness.
This is feasible to do, can be applied to any of the solutions discussed herein,
and is probably a good idea.  E.g.:
</p>

<blockquote><pre>
double get_double();
int    get_int();
forward&lt;int&gt;(get_double());  <font color="#C80000">// forward an rvalue double as an rvalue int:  Error, should not compile</font>
forward&lt;int&gt;(get_int());     <font color="#C80000">// forward an rvalue int as an rvalue int:     Ok</font>
</pre></blockquote>

<hr/>

<p>
Paper
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html">N2831</a>
"Fixing a Safety Problem with Rvalue References: Proposed Wording"
recommends certain language and library changes
to prevent accidentally applying move semantics to an lvalue.
I am in favor of the proposed language changes
and, with a single exception,
I am also in favor of the proposed library changes.
</p>

<p>
That single exception,
the specification of <tt>forward</tt>,
is the subject of this paper.
I will compare the behaviors of <tt>forward</tt>
as specified in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
and
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>,
and will contrast those
with a proposed third specification whose behavior I believe to be:
</p>

<ul>
  <li> more useful than that of
       <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>,</li>
  <li> as useful as that of
       <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>,
       and</li>
  <li>slightly safer to use than either of these.</li>
</ul>

<p>
In particular,
I believe the 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
<tt>forward</tt>
unnecessarily causes some safe, valid and reasonable code
to fail at compile time.
After contrasting the three behaviors,
I will present an example
that demonstrates the impact of the the various specifications.
</p>

<h2><a name="forward"></a><tt>forward</tt> Revealed</h2>

<p>
To examine the behaviors
of the various specifications
of <tt>forward</tt>,
eight cases must be considered,
shown in the "Call" column of the following table:
</p>

<blockquote>
<table border="1">
<tr>
  <th>Case #</th>
  <th>Call</th>
  <th>Description</th>
  <th><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a> result</th>
  <th><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a> result</th>
  <th>Proposed result</th>
</tr>
<tr bgcolor="#BCD2E6">
  <td align="center">1</td>
  <td><pre>forward&lt;      A&amp;&gt;(lvalue A)</pre></td>
  <td>Forward a non-const lvalue as a non-const lvalue</td>
  <td><pre>lvalue A</pre></td>
  <td><pre>lvalue A</pre></td>
  <td><pre>lvalue A</pre></td>
</tr>
<tr bgcolor="#BCD2E6">
  <td align="center">2</td>
  <td><pre>forward&lt;const A&amp;&gt;(lvalue A)</pre></td>
  <td>Forward an lvalue as a const lvalue</td>
  <td><pre>lvalue const A</pre></td>
  <td><pre>lvalue const A</pre></td>
  <td><pre>lvalue const A</pre></td>
</tr>
<tr bgcolor="#E6D2BC">
  <td align="center">3</td>
  <td><pre>forward&lt;      A&amp;&gt;(rvalue A)</pre></td>
  <td>Forward a non-const rvalue as a non-const lvalue</td>
  <td><center>rejected</center></td>
  <td><center>rejected</center></td>
  <td><center>rejected</center></td>
</tr>
<tr bgcolor="#E6D2BC">
  <td align="center">4</td>
  <td><pre>forward&lt;const A&amp;&gt;(rvalue A)</pre></td>
  <td>Forward an rvalue as a const lvalue</td>
  <td><pre>lvalue const A</pre></td>
  <td><pre>lvalue const A</pre></td>
  <td><center><b>rejected</b></center></td>
</tr>
<tr bgcolor="#BCD2E6">
  <td align="center">5</td>
  <td><pre>forward&lt;      A &gt;(lvalue A)</pre></td>
  <td>Forward a non-const lvalue as a non-const rvalue</td>
  <td><pre>rvalue A</pre></td>
  <td><pre>rvalue A</pre></td>
  <td><pre>rvalue A</pre></td>
</tr>
<tr bgcolor="#BCD2E6">
  <td align="center">6</td>
  <td><pre>forward&lt;const A &gt;(lvalue A)</pre></td>
  <td>Forward an lvalue as a const rvalue</td>
  <td><pre>rvalue const A</pre></td>
  <td><pre>rvalue const A</pre></td>
  <td><pre>rvalue const A</pre></td>
</tr>
<tr bgcolor="#E6D2BC">
  <td align="center">7</td>
  <td><pre>forward&lt;      A &gt;(rvalue A)</pre></td>
  <td>Forward a non-const rvalue as a non-const rvalue</td>
  <td><pre>rvalue A</pre></td>
  <td><center><center><b>rejected</b></center></center></td>
  <td><pre>rvalue A</pre></td>
</tr>
<tr bgcolor="#E6D2BC">
  <td align="center">8</td>
  <td><pre>forward&lt;const A &gt;(rvalue A)</pre></td>
  <td>Forward an rvalue as a const rvalue</td>
  <td><pre>rvalue const A</pre></td>
  <td><pre>rvalue const A</pre></td>
  <td><pre>rvalue const A</pre></td>
</tr>
</table>
</blockquote>

<p>
As summarized in the above table,
there is already agreement in six of the eight cases.
Only cases 4 and 7 are in dispute:
should <tt>forward</tt> reject case 4, case 7, or neither?
In the next section,
I will present an example to motivate the behavior
(shown in the right column above)
that I propose in this paper,
namely that
one ought not forward an rvalue as an lvalue,
but that all other forwarding is sensible, including forwarding rvalues
as rvalues.
</p>

<h2><a name="example"></a>Example</h2>

<p>
The example code is a sketch of a container (I
call it <tt>C</tt>) which is capable of holding either object types or
lvalue references (similar to <tt>tuple</tt> and <tt>pair</tt>).  I will refer
to the container's element type as either <tt>A</tt> or <tt>A&amp;</tt> to
specify when I'm referring to an object element type or an lvalue reference
element type which the container contains.
<tt>C</tt> has
a constructor which will take an rvalue argument of some other type of container
(<tt>U</tt>) which holds an <tt>A</tt> or <tt>A&amp;</tt>:
</p>

<blockquote><pre>
U u;
C&lt;A&gt; c(std::move(u));
</pre></blockquote>

<p>
This paper will concentrate on the implementation of this constructor for its
example.
</p>

<p>
The container <tt>U</tt> has a (possibly overloaded) member <tt>get()</tt> for accessing the
contained value.
</p>

<blockquote><pre>
A a = u.get();
</pre></blockquote>

<p>
It is via this <tt>u.get()</tt> interface that the container <tt>C</tt> will gain
access to <tt>U</tt>'s element, move constructing in case the element type is
<tt>A</tt>, else copy constructing for element types of <tt>A&amp;</tt>.
</p>

<p>
To simplify the discussion, I will neglect any other data members of <tt>C</tt>, including
those that might participate in this constructor.  I will also assume (for simplification)
that the contained type of <tt>C</tt> and the contained type of <tt>U</tt> have the same
type (no conversions).
</p>

<blockquote>
<p>
[<i>Footnote:</i>  The "same type" restriction above, and mentioned in the concepts below,
caused some concern, or at the very least curiosity with some reviewers.  Real world
code may well relax this restriction and this would typically involve using
<tt>forward&lt;U::value_type&gt;(u.get())</tt> instead of the <tt>forward&lt;T&gt;(u.get())</tt>
shown below.  Everything still works the same, though it becomes even more important for
<tt>forward</tt> to have "good behavior" because things also get more complicated to
reason about.  This paper is striving to avoid this complication because though
sometimes necessary in real world code (e.g. <tt>unique_ptr</tt>), the main point of the paper can be
demonstrated without this extra complication.]
</p>
</blockquote>

<p>
One degree of flexibility I would like to allow however is that the <tt>get()</tt>
accessor of <tt>U</tt> may return any of <tt>A&amp;</tt>, <tt>A&amp;&amp;</tt>,
or <tt>A</tt>.  The author of <tt>C</tt> does not know nor care about the specific
return of <tt>U::get()</tt>.  He simply wants <tt>C</tt> to work correctly no
matter what the client <tt>U</tt> throws at him.
</p>

<p>
Here is a conceptized implementation of the constructor:
</p>

<blockquote><pre>
<font color="#C80000">// T can be A or A&amp;</font>
template &lt;std::VariableType T&gt;
requires !std::RvalueReference&lt;T&gt;
class C
{
    T t_;
public:
    <font color="#C80000">// Move construct t_ from u.get() if T is A,</font>
    <font color="#C80000">//   else copy construct t_ from u.get() when T is A&amp;.</font>
    <font color="#C80000">//   u.get() may return T&amp;, T&amp;&amp; or T (which</font>
    <font color="#C80000">//   all collapse to A&amp; when T is A&amp;).  This</font>
    <font color="#C80000">//   constructor should always just do the right thing regardless.</font>
    template &lt;class U&gt;
      requires !std::LvalueReference&lt;U&gt;
            &amp;&amp; std::IsSame&lt;U::value_type, T&gt;
            &amp;&amp; ConstructibleFromForwardGet&lt;T, U&gt;
      explicit C(U&amp;&amp; u)
        : t_(std::forward&lt;T&gt;(u.get())) {}
};
</pre></blockquote>

<p>
My use of concepts in this example should not imply that this is a concepts
issue, it is not.  This is an issue concerning the functionality of <tt>forward</tt>,
and how
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
proposes to alter that functionality.  I have the same concerns about <tt>forward</tt>
whether it is used with concepts or not. Here is the same constructor written without
concepts:
</p>

<blockquote><pre>
template &lt;class T&gt;
class C
{
    T t_;
public:
    <font color="#C80000">// Move construct t_ from u.get() if T is A,</font>
    <font color="#C80000">//   else copy construct t_ from u.get() when T is A&amp;.</font>
    <font color="#C80000">//   u.get() may return T&amp;, T&amp;&amp; or T.</font>
    template &lt;class U&gt;
      explicit C(U&amp;&amp; u,
          typename std::enable_if
                     &lt;
                       !std::is_lvalue_reference&lt;U&gt;::value
                     &gt;::type* = 0)
        : t_(std::forward&lt;T&gt;(u.get())) {}
};
</pre></blockquote>

<p>
Disclaimer: Testing for this paper used the non-concepts version.
</p>

<p>
With the
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>
specification of <tt>forward</tt> the above constructor works as desired (confirmed with tests)
for all cases <tt>A</tt> and <tt>A&amp;</tt> with <tt>u.get()</tt> returning either
an lvalue or rvalue (except for one case which
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
doesn't fix, but is fixed by this proposal).
</p>

<p>
With the
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
specification of <tt>forward</tt> the above constructor fails with the following
quite reasonable code:
</p>

<blockquote><pre>
struct A {};

class U
{
    A a_;  // value_type is A
public:
    A get() {return a_;}
};

int main()
{
    U u;
    C&lt;A&gt; c(std::move(u));
}

test.cpp: In constructor 'C&lt;T&gt;::C(U&amp;&amp;, typename
          std::enable_if&lt;(!
          std::is_lvalue_reference::value), void&gt;::type*) [with
          U = U, T = A]':
test.cpp:40:   instantiated from here
test.cpp:18: error: no matching function for call to 'forward(A)'
</pre></blockquote>

<p>
In <tt>C</tt>'s constructor, <tt>u.get()</tt> is returning
an rvalue <tt>A</tt> which the 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
<tt>forward&lt;A&gt;</tt> summarily rejects (case #7).  This should be an identity
operation (forward a non-const rvalue as a non-const rvalue).  No other identity operations are rejected by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>,
including forwarding a const rvalue as a const rvalue.
</p>

<p>
I believe if we adopt the
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
<tt>forward</tt> specification, the author of <tt>C</tt> will simply (and rightly)
avoid <tt>std::forward</tt>:
</p>

<blockquote><pre>
explicit C(U&amp;&amp; u)
  : t_(<del>std::forward&lt;T&gt;</del><ins>static_cast&lt;T&amp;&amp;&gt;</ins>(u.get())) {}
</pre></blockquote>

<p>
I can see no motivation for pushing the author of <tt>C</tt> away from the use of
<tt>forward</tt>.  Indeed I believe we can make the use of <tt>forward</tt> superior
to the use of <tt>static_cast</tt> (see below).
</p>

<p>
Note that the use of <tt>move</tt> is not appropriate here as it would break the case when <tt>T</tt>
is <tt>A&amp;</tt>
</p>

<blockquote><pre>
explicit C(U&amp;&amp; u)              <font color="#C80000">// Wrong!</font>
  : t_(std::<b>move</b>(u.get())) {}  <font color="#C80000">// binds rvalue to a non-const ref when T is A&amp;</font>
</pre></blockquote>

<p>
Note further that simply copy constructing is not appropriate here as it would break the case when <tt>T</tt>
is <tt>A</tt> and <tt>u.get()</tt> returns an lvalue:
</p>

<blockquote><pre>
explicit C(U&amp;&amp; u)   <font color="#C80000">// Wrong!</font>
  : t_(u.get()) {}  <font color="#C80000">// copy constructs t_ instead of move constructs</font>
                    <font color="#C80000">// when T is A and u.get() returns an lvalue</font>
</pre></blockquote>

<p>
I alluded above to one problem which both the
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>
and 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
specifications allow and shouldn't:
</p>

<blockquote><pre>
class U
{
    const A&amp; a_;  // value_type is const A&amp;
public:
    U(const A&amp; a) : a_(a) {}
    <b>A</b> get() {return a_;}
};

int main()
{
    A a;
    U u(a);
    C&lt;<b>const A&amp;</b>&gt; c(std::move(u));
    <font color="#C80000">// c.t_ dangles here</font>
}
</pre></blockquote>

<p>
Here the rvalue returned from <tt>u.get()</tt> is binding to <tt>C's</tt> internal
<tt>const A&amp;</tt>.  After the constructor completes, this internal reference
is left dangling.  The danger is that we're allowing an rvalue to be forwarded
as an lvalue (case #4).
</p>

<p>
To fix this problem (and the one that
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>
attempts to introduce), we should <i>only</i> outlaw forwarding rvalues as lvalues.
With this specification, the author of <tt>C</tt> has both readability and
safety motivations to use <tt>std::forward</tt> instead of <tt>static_cast</tt>:
</p>

<blockquote><pre>
<font color="#C80000">// Works when it is supposed to.</font>
<font color="#C80000">// Doesn't work when it is not supposed to.</font>
explicit C(U&amp;&amp; u)
  : t_(<ins>std::forward&lt;T&gt;</ins><del>static_cast&lt;T&amp;&amp;&gt;</del>(u.get())) {}
</pre></blockquote>


<h2><a name="proposed"></a>Proposed Wording</h2>

<p>
This wording is consistent with the proposed wording of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html">N2831</a>
except for
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html#20.2.2">N2831</a>'s
modifications to <tt>forward</tt>.  It implements forwarding except for
rejecting cases #3 and #4 as described in the previous section.
</p>

<p>
Change the <tt>&lt;utility&gt;</tt> synopsis in 20.2 [utility]:
</p>

<blockquote><pre>
// <i>20.2.2, forward/move: </i>
template &lt;IdentityOf T&gt; <ins>requires !LvalueReference&lt;T&gt;</ins> T&amp;&amp; forward(IdentityOf&lt;T&gt;::type&amp;<del>&amp;</del>); 
<ins>template &lt;IdentityOf T&gt; requires !LvalueReference&lt;T&gt; T&amp;&amp; forward(RvalueOf&lt;T&gt;::type t);</ins>
<ins>template &lt;IdentityOf T&gt; requires LvalueReference&lt;T&gt; T forward(IdentityOf&lt;T&gt;::type t);</ins>
<ins>template &lt;IdentityOf T&gt; requires LvalueReference&lt;T&gt; T forward(RvalueOf&lt;T&gt;::type t) = delete;</ins>
template &lt;RvalueOf T&gt; RvalueOf&lt;T&gt;::type move(T&amp;&amp;);
</pre></blockquote>

<p>
Change 20.2.2 [forward]:
</p>

<blockquote>
<pre>
<ins>// forward lvalue as rvalue</ins>
template &lt;IdentityOf T&gt;
  <ins>requires !LvalueReference&lt;T&gt;</ins>
  T&amp;&amp;
  forward(IdentityOf&lt;T&gt;::type&amp;<del>&amp;</del> t);
</pre>

<pre>
<ins>// forward rvalue as rvalue</ins>
<ins>template &lt;IdentityOf T&gt;</ins>
  <ins>requires !LvalueReference&lt;T&gt;</ins>
  <ins>T&amp;&amp;</ins>
  <ins>forward(RvalueOf&lt;T&gt;::type t);</ins>
</pre>

<blockquote>
<p>...</p>

<p>
-3- <i>Returns:</i> <tt><ins>static_cast&lt;T&amp;&amp;&gt;(</ins>t<ins>)</ins></tt>.
</p>

</blockquote>

<pre>
<ins>// forward lvalue as lvalue</ins>
<ins>template &lt;IdentityOf T&gt;</ins>
  <ins>requires LvalueReference&lt;T&gt;</ins>
  <ins>T</ins>
  <ins>forward(IdentityOf&lt;T&gt;::type t);</ins>
</pre>

<blockquote>

<p>
<ins><i>Returns:</i> <tt>t</tt>.</ins>
</p>

<p>
<ins><i>Note:</i> The forwarding of rvalues as lvalues is intentionally disabled
to prevent dangling reference accidents when binding an rvalue to an lvalue reference to const.</ins>
</p>

</blockquote>

<blockquote>
<p>
-4- [<i>Example:</i> ...
</p>

</blockquote>

</blockquote>

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

<p>
The generous help of Daniel Kr&uuml;gler, Peter Dimov and Walter Brown
is gratefully acknowledged.  This is a much clearer paper thanks to their
excellent recommendations.
</p>

<p>
I would also like to acknowledge the work of David Abrahams and especially
Douglas Gregor in the preparation of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html">N2831</a>.
I believe
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2831.html">N2831</a>
is a significant improvement to our current draft standard
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf">N2800</a>,
excepting this one debate with <tt>forward</tt>.
</p>

</body>
</html>
