<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<title>US 90</title>
    <style type="text/css">
    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:#A0FFA0}
    del {background-color:#FFA0A0}
    </style>
</head>
<body>

<address align=right>
Document number: N3143=10-0133<br>
<br>
<a href="mailto:howard.hinnant@gmail.com">Howard Hinnant</a><br>
<a href="mailto:daniel.kruegler@googlemail.com">Daniel Kr&uuml;gler</a><br>

2010-10-15
</address>
<hr>
<h1 align=center>Proposed wording for US 90</h1>

<p>
US 90 compains that the following code does not work as desired:
</p>

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

struct Base { Base(Base&amp;&amp;); };

struct Derived
: private Base
{
    Derived(Derived&amp;&amp; d)
        : Base(std::forward&lt;Base&gt;(d)) { }
};

<font color="#C80000">// error: forward can not access Derived's private Base</font>
</pre></blockquote>

<p>
We looked at this in Rapperswil and came to the mistaken conclusion that the
proposed resolution (adopting a design such as that in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2835.html">N2835</a>)
would suffer the same error.
</p>

<p>
We were wrong.  Jason Merrill corrected me.  The key is to force the implicit
conversion from <tt>Derived</tt> to <tt>Base</tt> <em>outside</em> of
<tt>forward</tt>, as was done in N2835.
</p>

<p>
N2835 used four overloads to achieve the desired result.  The <i>desired result</i>
includes passing all 6 tests outlined in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html">N2951</a>.
Daniel Kr&uuml;gler showed how this same behavior can be achieved with only two
overloads, and Daniel's formulation is proposed herein.
</p>

<p>
For implementors:  The "ill-formed" requirement in p3 can be implemented with
a <tt>static_assert</tt> which tests that <tt>T</tt> is not an lvalue reference.
</p>

<p>
Additionally Stephan T. Lavavej noted that the return statement for <tt>move</tt>
is lacking the necessary cast, so that has been corrected as well.
</p>

<h2>Proposed Wording</h2>

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

<blockquote><pre>
<del>template &lt;class T, class U&gt; T&amp;&amp; forward(U&amp;&amp; u);</del>
<ins>template &lt;class T&gt; T&amp;&amp; forward(typename remove_reference&lt;T&gt;::type&amp; t);</ins>
<ins>template &lt;class T&gt; T&amp;&amp; forward(typename remove_reference&lt;T&gt;::type&amp;&amp; t);</ins>
</pre>
<blockquote>
<p>
2 <i>Returns:</i> <tt>static_cast&lt;T&amp;&amp;&gt;(<del>u</del><ins>t</ins>)</tt>.
</p>

<p>
3 <i>Remarks:</i>
<ins>If the second form is instantiated with an lvalue reference type, the
program is ill-formed.</ins>
<del>if the following constraints are not met, this signature shall
not participate in overload resolution:</del>
</p>

<ul>
<li><del>
the type formed by <tt>remove_reference&lt;U&gt;::type*</tt> is implicitly
convertible to the type <tt>remove_reference&lt;T&gt;::type*</tt>; and
</del></li>
<li><del>
if <tt>T</tt> is an lvalue reference type, then <tt>U</tt> is also an lvalue
reference type.
</del></li>
</ul>

<p>4 ...</p>
<p>5 ...</p>
</blockquote>

<pre>
template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp; t);
</pre>
<blockquote>
<p>
6 <i>Returns:</i> <tt><ins>static_cast&lt;typename remove_reference&lt;T&gt;::type&amp;&amp;&gt;(</ins>t<ins>)</ins></tt>.
</p>
</blockquote>

</blockquote>


</body>
</html>
