<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Onward,&#160;Forward!</title>
	<atom:link href="http://cpp-next.com/archive/2009/12/onward-forward/feed/" rel="self" type="application/rss+xml" />
	<link>http://cpp-next.com/archive/2009/12/onward-forward/</link>
	<description>The next generation of C++</description>
	<lastBuildDate>Mon, 30 Apr 2012 15:07:48 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	<item>
		<title>By: Functions that do nothing &#124; Andrzej&#039;s C++ blog</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-1758</link>
		<dc:creator>Functions that do nothing &#124; Andrzej&#039;s C++ blog</dc:creator>
		<pubDate>Fri, 11 Nov 2011 23:16:58 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-1758</guid>
		<description>&lt;p&gt;[...] the technique known as perfect forwarding. It has already been well explained by many authors: [1], [2], [3]. It is different than the previous moving functions in that it is only useful in function [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] the technique known as perfect forwarding. It has already been well explained by many authors: [1], [2], [3]. It is different than the previous moving functions in that it is only useful in function [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-287</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Sat, 20 Nov 2010 23:39:05 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-287</guid>
		<description>&lt;p&gt;I just noticed that in the case above, there&#039;s no way to forward rvalues as rvalues.  If forwarding erases rvalue-ness, move semantics loses much of its power.  Unless there&#039;s more that you haven&#039;t told me about this idea, it&#039;s just another one of those fatally-flawed ideas I noted below.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I just noticed that in the case above, there&#8217;s no way to forward rvalues as rvalues.  If forwarding erases rvalue-ness, move semantics loses much of its power.  Unless there&#8217;s more that you haven&#8217;t told me about this idea, it&#8217;s just another one of those fatally-flawed ideas I noted below.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sebastian</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-286</link>
		<dc:creator>Sebastian</dc:creator>
		<pubDate>Thu, 04 Mar 2010 16:54:36 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-286</guid>
		<description>&lt;p&gt;Reference collapsing is not to blame, IMHO. It&#039;s the template argument deduction rule, §14.9.2.1/3 to be specific. This is going to confuse a lot of people. It already has. I&#039;d also prefer a syntax that explicitly enables this deduction rule (or something similar).&lt;/p&gt;

&lt;p&gt;Cheers,
Sebastian&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Reference collapsing is not to blame, IMHO. It&#8217;s the template argument deduction rule, §14.9.2.1/3 to be specific. This is going to confuse a lot of people. It already has. I&#8217;d also prefer a syntax that explicitly enables this deduction rule (or something similar).</p>

<p>Cheers,
Sebastian</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-285</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Wed, 20 Jan 2010 12:14:43 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-285</guid>
		<description>&lt;p&gt;I guess the point is that the move/copy overloading pattern only applies when you know how to do the move; otherwise you might as well use a single function, with forwarding, to pass the argument on to something that &lt;em&gt;does&lt;/em&gt; know how to move it.  A generic &lt;code&gt;T&lt;/code&gt; isn&#039;t usually something you know how to move from.&lt;/p&gt;

&lt;p&gt;That said, this looks like another place where concepts reveal a flaw in the rvalue reference design.  Something like&lt;/p&gt;

&lt;pre&gt;struct X
&#123;
    template &lt;&lt;em&gt;SomeConcept&lt;/em&gt; T&gt;
    X&#040;T&amp;&amp;&#041;;
&#160;
    template &lt;&lt;em&gt;SomeConcept&lt;/em&gt; T&gt;
    X&#040;T const&amp;&#041;;
&#125;;&lt;/pre&gt;

&lt;p&gt;where it is known how to move from all models of &lt;code&gt;&lt;i&gt;SomeConcept&lt;/i&gt;&lt;/code&gt;, would be a problem.  In C++ without concepts, you can have the same problem if you replace &lt;code&gt;&lt;i&gt;SomeConcept&lt;/i&gt;&lt;/code&gt; with a SFINAE constraint:&lt;/p&gt;

&lt;pre&gt;struct X
&#123;
    template &lt;class T&gt;
    X&#040;T&amp;&amp;, typename enable_if&lt;&lt;i&gt;some_constraint&lt;/i&gt;&lt;T&gt; &gt;::type* = 0&#041;;
&#160;
    template &lt;class T&gt;
    X&#040;T const&amp;, typename enable_if&lt;&lt;i&gt;some_constraint&lt;/i&gt;&lt;T&gt; &gt;::type* = 0&#041;;
&#125;;&lt;/pre&gt;

&lt;p&gt;Still, as of today, no real use-case has cropped up that would cause the problem.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I guess the point is that the move/copy overloading pattern only applies when you know how to do the move; otherwise you might as well use a single function, with forwarding, to pass the argument on to something that <em>does</em> know how to move it.  A generic <code>T</code> isn&#8217;t usually something you know how to move from.</p>

<p>That said, this looks like another place where concepts reveal a flaw in the rvalue reference design.  Something like</p>

<pre>struct X
&#123;
    template &lt;<em>SomeConcept</em> T&gt;
    X&#040;T&amp;&amp;&#041;;
&nbsp;
    template &lt;<em>SomeConcept</em> T&gt;
    X&#040;T const&amp;&#041;;
&#125;;</pre>

<p>where it is known how to move from all models of <code><i>SomeConcept</i></code>, would be a problem.  In C++ without concepts, you can have the same problem if you replace <code><i>SomeConcept</i></code> with a SFINAE constraint:</p>

<pre>struct X
&#123;
    template &lt;class T&gt;
    X&#040;T&amp;&amp;, typename enable_if&lt;<i>some_constraint</i>&lt;T&gt; &gt;::type* = 0&#041;;
&nbsp;
    template &lt;class T&gt;
    X&#040;T const&amp;, typename enable_if&lt;<i>some_constraint</i>&lt;T&gt; &gt;::type* = 0&#041;;
&#125;;</pre>

<p>Still, as of today, no real use-case has cropped up that would cause the problem.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Howard Hinnant</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-284</link>
		<dc:creator>Howard Hinnant</dc:creator>
		<pubDate>Tue, 19 Jan 2010 17:48:18 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-284</guid>
		<description>&lt;p&gt;Without constraints, yes, #2 will always be chosen non-const lvalues if &quot;#1 isn&#039;t taken out of contention&quot;.  What Dave means is to use &quot;constrained templates&quot;.  My preference would be to constrain #2 to not accept lvalues (if I really wanted to write code this way):&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;
template&lt; typename Type,
          class = typename std::enable_if
          &lt;
              !std::is_lvalue_reference&lt;Type&gt;::value
          &gt;::type&gt;
void fun( Type &amp;&amp; )     // #2
{
    std::cout &lt;&lt; &quot;move&quot;;
}
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now fun(n) outputs &quot;copy&quot;.&lt;/p&gt;

&lt;p&gt;Alternatively you could put all of the logic under #2 since it will accept everything:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;
template&lt; typename Type&gt;
void fun( Type &amp;&amp; )     // #2
{
    if (std::is_lvalue_reference&lt;Type&gt;::value)
        std::cout &lt;&lt; &quot;copy&quot;;
    else
        std::cout &lt;&lt; &quot;move&quot;;
}

// fun(n) -&gt; copy
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;That &quot;run time if&quot; could also be a compile-time-if:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;
void fun_impl(std::true_type)
{
   std::cout &lt;&lt; &quot;copy&quot;;
}

void fun_impl(std::false_type)
{
   std::cout &lt;&lt; &quot;move&quot;;
}

template&lt; typename Type&gt;
void fun( Type &amp;&amp; )     // #2
{
    fun_impl(std::is_lvalue_reference&lt;Type&gt;());
}

// fun(n) -&gt; copy
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;There are lots of options, and the best one depends on what you want to do.  In practice I&#039;ve found that I don&#039;t usually want to overload T&amp;&amp; and const T&amp; for a truly generic T.  Far more often T is partially specialized.  E.g. I usually want to overload on vector&lt;T&gt;&amp;&amp; and const vector&lt;T&gt;&amp;.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Without constraints, yes, #2 will always be chosen non-const lvalues if &#8220;#1 isn&#8217;t taken out of contention&#8221;.  What Dave means is to use &#8220;constrained templates&#8221;.  My preference would be to constrain #2 to not accept lvalues (if I really wanted to write code this way):</p>

<p></p>

<blockquote><pre>
template&lt; typename Type,
          class = typename std::enable_if
          &lt;
              !std::is_lvalue_reference&lt;Type&gt;::value
          &gt;::type&gt;
void fun( Type &amp;&amp; )     // #2
{
    std::cout &lt;&lt; "move";
}
</pre></blockquote>

<p></p>

<p>Now fun(n) outputs &#8220;copy&#8221;.</p>

<p>Alternatively you could put all of the logic under #2 since it will accept everything:</p>

<p></p>

<blockquote><pre>
template&lt; typename Type&gt;
void fun( Type &amp;&amp; )     // #2
{
    if (std::is_lvalue_reference&lt;Type&gt;::value)
        std::cout &lt;&lt; "copy";
    else
        std::cout &lt;&lt; "move";
}

// fun(n) -&gt; copy
</pre></blockquote>

<p></p>

<p>That &#8220;run time if&#8221; could also be a compile-time-if:</p>

<p></p>

<blockquote><pre>
void fun_impl(std::true_type)
{
   std::cout &lt;&lt; "copy";
}

void fun_impl(std::false_type)
{
   std::cout &lt;&lt; "move";
}

template&lt; typename Type&gt;
void fun( Type &amp;&amp; )     // #2
{
    fun_impl(std::is_lvalue_reference&lt;Type&gt;());
}

// fun(n) -&gt; copy
</pre></blockquote>

<p></p>

<p>There are lots of options, and the best one depends on what you want to do.  In practice I&#8217;ve found that I don&#8217;t usually want to overload T&amp;&amp; and const T&amp; for a truly generic T.  Far more often T is partially specialized.  E.g. I usually want to overload on vector&lt;T&gt;&amp;&amp; and const vector&lt;T&gt;&amp;.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daveed Vandevoorde</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-283</link>
		<dc:creator>Daveed Vandevoorde</dc:creator>
		<pubDate>Tue, 19 Jan 2010 17:27:51 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-283</guid>
		<description>&lt;p&gt;Yes: I distinctly remember you, Howard, John S., Steve A., and myself having that discussion over lunch (but I don&#039;t recall the venue). (I think there were others -- not sure.) I believe that&#039;s also the time when the &amp;&amp; token was (mostly) settled on. John and I suggested parameter modifiers both for a bind-reference-to-rvalue mechanism and as a &quot;deduct-to-forward&quot; indication (I, informally, repeated that suggestion a couple of times later as the proposal took shape).&lt;/p&gt;

&lt;p&gt;I should note that I did not make the alternative suggestion because of specific issues I foresaw: It was just an intuition that introducing a new kind of reference would have difficult-to-tract ramifications and make the feature less accessible to the C++-programming community. (Had I anticipated the issues you and others have discovered since then, maybe I&#039;d been more forceful. :-&#124;)&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Yes: I distinctly remember you, Howard, John S., Steve A., and myself having that discussion over lunch (but I don&#8217;t recall the venue). (I think there were others &#8212; not sure.) I believe that&#8217;s also the time when the &amp;&amp; token was (mostly) settled on. John and I suggested parameter modifiers both for a bind-reference-to-rvalue mechanism and as a &#8220;deduct-to-forward&#8221; indication (I, informally, repeated that suggestion a couple of times later as the proposal took shape).</p>

<p>I should note that I did not make the alternative suggestion because of specific issues I foresaw: It was just an intuition that introducing a new kind of reference would have difficult-to-tract ramifications and make the feature less accessible to the C++-programming community. (Had I anticipated the issues you and others have discovered since then, maybe I&#8217;d been more forceful. <img src='http://cpp-next.com/wp-includes/images/smilies/icon_neutral.gif' alt=':-|' class='wp-smiley' /> )</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-282</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Tue, 19 Jan 2010 17:02:16 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-282</guid>
		<description>&lt;p&gt;Was I around for any of these discussions?  Just curious, &#039;cause I don&#039;t remember them.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Was I around for any of these discussions?  Just curious, &#8217;cause I don&#8217;t remember them.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daveed Vandevoorde</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-281</link>
		<dc:creator>Daveed Vandevoorde</dc:creator>
		<pubDate>Tue, 19 Jan 2010 16:48:37 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-281</guid>
		<description>&lt;blockquote cite=&quot;comment-436&quot;&gt;

&lt;strong&gt;&lt;a href=&quot;#comment-436&quot; rel=&quot;nofollow&quot;&gt;Dave Abrahams&lt;/a&gt;&lt;/strong&gt;: Hi Daveed,
That’s perfectly true; I wrote imprecisely.There &lt;em&gt;were&lt;/em&gt; lots of other ideas raised, but you know as well as I do that there’s worlds of difference between “voicing a preference” and presenting a viable proposal.At one point (the previous Santa Cruz meeting), the committee sent us back to the drawing board to work on trying to realize some of the competing ideas.IIRC Jason Merrill was the only one who showed up for the in-depth conversations and his ideas turned out not to work.In fact, history is littered with approaches people thought were “obviously better,” that turned out to be fatally flawed in some way.I guess after seeing a few of those, I probably wasn’t ready to invest time in proposals that weren’t fairly complete and solid.
&#160;&#160;

&lt;/blockquote&gt;

&lt;p&gt;
&lt;/p&gt;

&lt;p&gt;True.&lt;/p&gt;

&lt;p&gt;I just wanted to clarify that we (you, I , Howard, etc.) &lt;em&gt;could&lt;/em&gt; think (and &lt;em&gt;had&lt;/em&gt; thought) of other ways.  There were from the start people (e.g., colleagues and I) who thought the merging of &quot;moving&quot; and &quot;forwarding&quot; was a terrible idea, and we sketched out &quot;other ways&quot; (where &quot;from the start&quot; means during informal discussions, before a formal rvalue reference proposal was made).&lt;/p&gt;

&lt;p&gt;My bad for not putting in the energy to push those sketches forward as a competing proposal.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<blockquote cite="comment-436">

<strong><a href="#comment-436" rel="nofollow">Dave Abrahams</a></strong>: Hi Daveed,
That’s perfectly true; I wrote imprecisely.There <em>were</em> lots of other ideas raised, but you know as well as I do that there’s worlds of difference between “voicing a preference” and presenting a viable proposal.At one point (the previous Santa Cruz meeting), the committee sent us back to the drawing board to work on trying to realize some of the competing ideas.IIRC Jason Merrill was the only one who showed up for the in-depth conversations and his ideas turned out not to work.In fact, history is littered with approaches people thought were “obviously better,” that turned out to be fatally flawed in some way.I guess after seeing a few of those, I probably wasn’t ready to invest time in proposals that weren’t fairly complete and solid.
&nbsp;&nbsp;

</blockquote>

<p>
</p>

<p>True.</p>

<p>I just wanted to clarify that we (you, I , Howard, etc.) <em>could</em> think (and <em>had</em> thought) of other ways.  There were from the start people (e.g., colleagues and I) who thought the merging of &#8220;moving&#8221; and &#8220;forwarding&#8221; was a terrible idea, and we sketched out &#8220;other ways&#8221; (where &#8220;from the start&#8221; means during informal discussions, before a formal rvalue reference proposal was made).</p>

<p>My bad for not putting in the energy to push those sketches forward as a competing proposal.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-280</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Tue, 19 Jan 2010 15:27:18 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-280</guid>
		<description>&lt;p&gt;Hi Daveed,&lt;/p&gt;

&lt;p&gt;That&#039;s perfectly true; I wrote imprecisely.  There &lt;em&gt;were&lt;/em&gt; lots of other ideas raised, but you know as well as I do that there&#039;s worlds of difference between &quot;voicing a preference&quot; and presenting a viable proposal.  At one point (the previous Santa Cruz meeting), the committee sent us back to the drawing board to work on trying to realize some of the competing ideas.  IIRC Jason Merrill was the only one who showed up for the in-depth conversations and his ideas turned out not to work.  In fact, history is littered with approaches people thought were &quot;obviously better,&quot; that turned out to be fatally flawed in some way.  I guess after seeing a few of those, I probably wasn&#039;t ready to invest time in proposals that weren&#039;t fairly complete and solid.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Hi Daveed,</p>

<p>That&#8217;s perfectly true; I wrote imprecisely.  There <em>were</em> lots of other ideas raised, but you know as well as I do that there&#8217;s worlds of difference between &#8220;voicing a preference&#8221; and presenting a viable proposal.  At one point (the previous Santa Cruz meeting), the committee sent us back to the drawing board to work on trying to realize some of the competing ideas.  IIRC Jason Merrill was the only one who showed up for the in-depth conversations and his ideas turned out not to work.  In fact, history is littered with approaches people thought were &#8220;obviously better,&#8221; that turned out to be fatally flawed in some way.  I guess after seeing a few of those, I probably wasn&#8217;t ready to invest time in proposals that weren&#8217;t fairly complete and solid.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daveed Vandevoorde</title>
		<link>http://cpp-next.com/archive/2009/12/onward-forward/comment-page-1/#comment-279</link>
		<dc:creator>Daveed Vandevoorde</dc:creator>
		<pubDate>Tue, 19 Jan 2010 14:56:07 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=622#comment-279</guid>
		<description>&lt;blockquote cite=&quot;comment-429&quot;&gt;

&lt;strong&gt;&lt;a href=&quot;#comment-429&quot; rel=&quot;nofollow&quot;&gt;Dave Abrahams&lt;/a&gt;&lt;/strong&gt;: The short answer is, “because we couldn’t think of another way.”

&lt;/blockquote&gt;

&lt;blockquote cite=&quot;comment-429&quot;&gt;

&lt;strong&gt;&lt;a href=&quot;#comment-429&quot; rel=&quot;nofollow&quot;&gt;Dave Abrahams&lt;/a&gt;&lt;/strong&gt;: The short answer is, “because we couldn’t think of another way.”And if you want to know why your idea almost certainly wouldn’t be accepted, it’s just because it’s now too late in the standardization cycle.All I can say is, “where have you been for the past 10 years?”I would have welcomed ideas like this one.
&#160;&#160;

&lt;/blockquote&gt;

&lt;p&gt;I don&#039;t think that&#039;s quite right: I (and others) voiced my preference for not trying to fit everything under the rvalue reference type, and instead introduce forwarding-specific notation.  E.g.:&lt;/p&gt;

&lt;p&gt;template void ff(for T) { ... }  // T deduced to &amp; or &amp;&amp;&lt;/p&gt;

&lt;p&gt;(I also suggested not introducing rvalue reference types at all, and handle rvalue-vs-lvalue overloading with another parameter modifier.)&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<blockquote cite="comment-429">

<strong><a href="#comment-429" rel="nofollow">Dave Abrahams</a></strong>: The short answer is, “because we couldn’t think of another way.”

</blockquote>

<blockquote cite="comment-429">

<strong><a href="#comment-429" rel="nofollow">Dave Abrahams</a></strong>: The short answer is, “because we couldn’t think of another way.”And if you want to know why your idea almost certainly wouldn’t be accepted, it’s just because it’s now too late in the standardization cycle.All I can say is, “where have you been for the past 10 years?”I would have welcomed ideas like this one.
&nbsp;&nbsp;

</blockquote>

<p>I don&#8217;t think that&#8217;s quite right: I (and others) voiced my preference for not trying to fit everything under the rvalue reference type, and instead introduce forwarding-specific notation.  E.g.:</p>

<p>template void ff(for T) { &#8230; }  // T deduced to &amp; or &amp;&amp;</p>

<p>(I also suggested not introducing rvalue reference types at all, and handle rvalue-vs-lvalue overloading with another parameter modifier.)</p>
]]></content:encoded>
	</item>
</channel>
</rss>

