<?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: Your Next&#160;Assignment&#8230;</title>
	<atom:link href="http://cpp-next.com/archive/2009/09/your-next-assignment/feed/" rel="self" type="application/rss+xml" />
	<link>http://cpp-next.com/archive/2009/09/your-next-assignment/</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: Michal Mocny</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-307</link>
		<dc:creator>Michal Mocny</dc:creator>
		<pubDate>Tue, 20 Jul 2010 15:12:00 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-307</guid>
		<description>&lt;p&gt;Thanks.  I agree that there isn&#039;t a canonical move assignment, and just noted that I tried to ignore the performance aspect entirely and came to the same conclusion regardless.&lt;/p&gt;

&lt;p&gt;Thank goodness default move constructor/assignment was added to the (draft) standard.&lt;/p&gt;

&lt;p&gt;Great read, thanks for the series.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Thanks.  I agree that there isn&#8217;t a canonical move assignment, and just noted that I tried to ignore the performance aspect entirely and came to the same conclusion regardless.</p>

<p>Thank goodness default move constructor/assignment was added to the (draft) standard.</p>

<p>Great read, thanks for the series.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-306</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Tue, 20 Jul 2010 15:06:19 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-306</guid>
		<description>&lt;blockquote cite=&quot;comment-697&quot;&gt;

calling std::swap(*this, rhs); inside the move assignment operator of the “clear, and swap” will likely lead to a infinite call loop, since the default std::swap is defined using move assignment. I just changed this to this-&gt;swap(rhs); for a type I was writing.

&lt;/blockquote&gt;

&lt;p&gt;Not in this case.  You forget that there&#039;s a &lt;code&gt;std::swap&lt;/code&gt; overload for &lt;code&gt;std::vector&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote cite=&quot;comment-697&quot;&gt;
More-so than performance issues, I think that it is too bad that the canonical move assignment operator relies on a specialized definition of swap, since the promise of “if your type is movable, you can just use the default std::swap” was a big benefit. Now its a chicken and egg thing for canonical swap (need swap for move, need move for swap).
&lt;/blockquote&gt;

&lt;p&gt;It would make sense for adapting a legacy type that had already implemented &lt;code&gt;swap&lt;/code&gt;, but one of the real points of this article is that there really isn&#039;t  a suitable &quot;canonical move assignment.&quot;&lt;/p&gt;

&lt;blockquote cite=&quot;comment-697&quot;&gt;
Hopefully most of the time the “= default” move operators will suffice, and when they don’t, hopefully writing a specialized move operator is warranted anyway.

As a side note, the only other reason I can think of to still write a swap member is to allow swap-with-temporary. So, could swap-with-temporary be replaced with move assignment? T().swap(t)  t = T(); ? The only times I used swap-with-temp before was for non copyable objects or when copy semantics were insufficient (ie, shrinking vector capacity). Seems move assignment covers those basis?

&lt;/blockquote&gt;

&lt;p&gt;Probably.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<blockquote cite="comment-697">

calling std::swap(*this, rhs); inside the move assignment operator of the “clear, and swap” will likely lead to a infinite call loop, since the default std::swap is defined using move assignment. I just changed this to this-&gt;swap(rhs); for a type I was writing.

</blockquote>

<p>Not in this case.  You forget that there&#8217;s a <code>std::swap</code> overload for <code>std::vector</code>.</p>

<blockquote cite="comment-697">
More-so than performance issues, I think that it is too bad that the canonical move assignment operator relies on a specialized definition of swap, since the promise of “if your type is movable, you can just use the default std::swap” was a big benefit. Now its a chicken and egg thing for canonical swap (need swap for move, need move for swap).
</blockquote>

<p>It would make sense for adapting a legacy type that had already implemented <code>swap</code>, but one of the real points of this article is that there really isn&#8217;t  a suitable &#8220;canonical move assignment.&#8221;</p>

<blockquote cite="comment-697">
Hopefully most of the time the “= default” move operators will suffice, and when they don’t, hopefully writing a specialized move operator is warranted anyway.

As a side note, the only other reason I can think of to still write a swap member is to allow swap-with-temporary. So, could swap-with-temporary be replaced with move assignment? T().swap(t)  t = T(); ? The only times I used swap-with-temp before was for non copyable objects or when copy semantics were insufficient (ie, shrinking vector capacity). Seems move assignment covers those basis?

</blockquote>

<p>Probably.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michal Mocny</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-305</link>
		<dc:creator>Michal Mocny</dc:creator>
		<pubDate>Tue, 20 Jul 2010 14:32:25 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-305</guid>
		<description>&lt;p&gt;First, a minor point: calling std::swap(*this, rhs); inside the move assignment operator of the &quot;clear, and swap&quot; will likely lead to a infinite call loop, since the default std::swap is defined using move assignment.  I just changed this to this-&gt;swap(rhs); for a type I was writing.&lt;/p&gt;

&lt;p&gt;More-so than performance issues, I think that it is too bad that the canonical move assignment operator relies on a specialized definition of swap, since the promise of &quot;if your type is movable, you can just use the default std::swap&quot; was a big benefit.  Now its a chicken and egg thing for canonical swap (need swap for move, need move for swap).&lt;/p&gt;

&lt;p&gt;Hopefully most of the time the &quot;= default&quot; move operators will suffice, and when they don&#039;t, hopefully writing a specialized move operator is warranted anyway.&lt;/p&gt;

&lt;p&gt;As a side note, the only other reason I can think of to still write a swap member is to allow swap-with-temporary.  So, could swap-with-temporary be replaced with move assignment?  T().swap(t) &lt;=?replaceable?=&gt; t = T(); ?  The only times I used swap-with-temp before was for non copyable objects or when copy semantics were insufficient (ie, shrinking vector capacity).  Seems move assignment covers those basis?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>First, a minor point: calling std::swap(*this, rhs); inside the move assignment operator of the &#8220;clear, and swap&#8221; will likely lead to a infinite call loop, since the default std::swap is defined using move assignment.  I just changed this to this-&gt;swap(rhs); for a type I was writing.</p>

<p>More-so than performance issues, I think that it is too bad that the canonical move assignment operator relies on a specialized definition of swap, since the promise of &#8220;if your type is movable, you can just use the default std::swap&#8221; was a big benefit.  Now its a chicken and egg thing for canonical swap (need swap for move, need move for swap).</p>

<p>Hopefully most of the time the &#8220;= default&#8221; move operators will suffice, and when they don&#8217;t, hopefully writing a specialized move operator is warranted anyway.</p>

<p>As a side note, the only other reason I can think of to still write a swap member is to allow swap-with-temporary.  So, could swap-with-temporary be replaced with move assignment?  T().swap(t) &lt;=?replaceable?=&gt; t = T(); ?  The only times I used swap-with-temp before was for non copyable objects or when copy semantics were insufficient (ie, shrinking vector capacity).  Seems move assignment covers those basis?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sean Parent</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-304</link>
		<dc:creator>Sean Parent</dc:creator>
		<pubDate>Wed, 26 May 2010 17:45:25 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-304</guid>
		<description>&lt;p&gt;I think &quot;don&#039;t do that&quot; is a bad answer - self move, like self assignment, should be a no-op. Otherwise writing permutation algorithms (like sort) get considerably more complex. That&#039;s one attraction to the formulaic swap - it gets self move correct. In your optimal version, I don&#039;t think a check for self move will cost you much.&lt;/p&gt;

&lt;p&gt;Generally, I think it is likely worth the effort to squeeze cycles out of std::vector but I think it is much better to teach the formulaic &quot;pass by value and swap&quot; assignment because it is so much easier to get correct. I&#039;ve come across a lot of code that blows the self-assignment case.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I think &#8220;don&#8217;t do that&#8221; is a bad answer &#8211; self move, like self assignment, should be a no-op. Otherwise writing permutation algorithms (like sort) get considerably more complex. That&#8217;s one attraction to the formulaic swap &#8211; it gets self move correct. In your optimal version, I don&#8217;t think a check for self move will cost you much.</p>

<p>Generally, I think it is likely worth the effort to squeeze cycles out of std::vector but I think it is much better to teach the formulaic &#8220;pass by value and swap&#8221; assignment because it is so much easier to get correct. I&#8217;ve come across a lot of code that blows the self-assignment case.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-303</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Wed, 26 May 2010 12:43:28 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-303</guid>
		<description>&lt;p&gt;IIRC Howard&#039;s answer was &quot;don&#039;t do that,&quot; but I could be misremembering&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>IIRC Howard&#8217;s answer was &#8220;don&#8217;t do that,&#8221; but I could be misremembering</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott M</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-302</link>
		<dc:creator>Scott M</dc:creator>
		<pubDate>Thu, 29 Apr 2010 21:33:51 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-302</guid>
		<description>&lt;p&gt;What&#039;s supposed to happen with move-assign-to-self?  Like x = std::move(x);&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>What&#8217;s supposed to happen with move-assign-to-self?  Like x = std::move(x);</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Thomas Petit</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-301</link>
		<dc:creator>Thomas Petit</dc:creator>
		<pubDate>Wed, 21 Oct 2009 12:41:04 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-301</guid>
		<description>&lt;blockquote cite=&quot;comment-189&quot;&gt;

&lt;strong&gt;&lt;a href=&quot;#comment-189&quot; rel=&quot;nofollow&quot;&gt;Dave Abrahams&lt;/a&gt;&lt;/strong&gt;: I don’t remember the details of how the optimization works, but I think it just had a special overload of &lt;CODE&gt;copy&lt;/CODE&gt; for when the inputs were &lt;CODE&gt;move_iterator&lt;/CODE&gt;s; you can crawl the code yourself to find out.&lt;/blockquote&gt;

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

&lt;p&gt;
Thanks.&lt;/p&gt;

&lt;p&gt;I finally look at the source, and it turns out that I misunderstood the comment &quot;libstdc++ (the GCC standard lib) has optimizations that can...&quot; &lt;i&gt;and&lt;/i&gt; was confused about what a move iterator is. :)&lt;/p&gt;

&lt;p&gt;So, actually :&lt;/p&gt;

&lt;p&gt;1) make_move_iterator have nothing to with that memmove optimization. memmove is called when the iterator value type is a pod, nothing else.&lt;/p&gt;

&lt;p&gt;2) A move iterator is an iterator &lt;i&gt;adaptor&lt;/i&gt;. (I missed that part :))&lt;/p&gt;

&lt;p&gt;3 )&lt;/p&gt;

&lt;pre&gt;std::copy&#040;std::make_move_iterator&#040;rhs.begin&#040;&#041;&#041;, std::make_move_iterator&#040;rhs.end&#040;&#041;&#041;, begin&#040;&#041;&#041;;&lt;/pre&gt;

&lt;p&gt;is a verbose way to write :&lt;/p&gt;

&lt;pre&gt;std::move&#040;rhs.begin&#040;&#041;, rhs.end&#040;&#041;, begin&#040;&#041;&#041;;&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<blockquote cite="comment-189">

<strong><a href="#comment-189" rel="nofollow">Dave Abrahams</a></strong>: I don’t remember the details of how the optimization works, but I think it just had a special overload of <code>copy</code> for when the inputs were <code>move_iterator</code>s; you can crawl the code yourself to find out.</blockquote>

<p></p>

<p>
Thanks.</p>

<p>I finally look at the source, and it turns out that I misunderstood the comment &#8220;libstdc++ (the GCC standard lib) has optimizations that can&#8230;&#8221; <i>and</i> was confused about what a move iterator is. <img src='http://cpp-next.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>So, actually :</p>

<p>1) make_move_iterator have nothing to with that memmove optimization. memmove is called when the iterator value type is a pod, nothing else.</p>

<p>2) A move iterator is an iterator <i>adaptor</i>. (I missed that part <img src='http://cpp-next.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p>

<p>3 )</p>

<pre>std::copy&#040;std::make_move_iterator&#040;rhs.begin&#040;&#041;&#041;, std::make_move_iterator&#040;rhs.end&#040;&#041;&#041;, begin&#040;&#041;&#041;;</pre>

<p>is a verbose way to write :</p>

<pre>std::move&#040;rhs.begin&#040;&#041;, rhs.end&#040;&#041;, begin&#040;&#041;&#041;;</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-300</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Mon, 05 Oct 2009 17:46:01 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-300</guid>
		<description>&lt;p&gt;I don&#039;t think that&#039;s a problem for the canonical move assignment:&lt;/p&gt;

&lt;pre&gt;template &lt;class X&gt;
template &lt;class Y&gt; shared_ptr&lt;X&gt;&amp;
shared_ptr&lt;X&gt;::operator=&#040;shared_ptr&lt;Y&gt; &amp;&amp;r&#041;
&#123;
     shared_ptr&#040; std::move&#040;r&#041; &#041;
         .swap&#040;*this&#041;;
     return *this;
&#125;&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p>I don&#8217;t think that&#8217;s a problem for the canonical move assignment:</p>

<pre>template &lt;class X&gt;
template &lt;class Y&gt; shared_ptr&lt;X&gt;&amp;
shared_ptr&lt;X&gt;::operator=&#040;shared_ptr&lt;Y&gt; &amp;&amp;r&#041;
&#123;
     shared_ptr&#040; std::move&#040;r&#041; &#041;
         .swap&#040;*this&#041;;
     return *this;
&#125;</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-299</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Mon, 05 Oct 2009 17:40:39 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-299</guid>
		<description>&lt;p&gt;I don&#039;t remember the details of how the optimization works, but I think it just had a special overload of &lt;code&gt;copy&lt;/code&gt; for when the inputs were &lt;code&gt;move_iterator&lt;/code&gt;s; you can crawl the code yourself to find out.&lt;/p&gt;

&lt;p&gt;As for MSVC 10, that would be a bug in their implementation.  &lt;code&gt;rhs&lt;/code&gt; is supposed to be treated  in expressions as a &lt;em&gt;non&lt;/em&gt;-const lvalue, so &lt;code&gt;_Ty&lt;/code&gt; should be deduced to be &lt;code&gt;alloc&lt;/code&gt;, not &lt;code&gt;const alloc&lt;/code&gt;.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I don&#8217;t remember the details of how the optimization works, but I think it just had a special overload of <code>copy</code> for when the inputs were <code>move_iterator</code>s; you can crawl the code yourself to find out.</p>

<p>As for MSVC 10, that would be a bug in their implementation.  <code>rhs</code> is supposed to be treated  in expressions as a <em>non</em>-const lvalue, so <code>_Ty</code> should be deduced to be <code>alloc</code>, not <code>const alloc</code>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave Abrahams</title>
		<link>http://cpp-next.com/archive/2009/09/your-next-assignment/comment-page-1/#comment-298</link>
		<dc:creator>Dave Abrahams</dc:creator>
		<pubDate>Wed, 30 Sep 2009 15:10:50 +0000</pubDate>
		<guid isPermaLink="false">http://cpp-next.com/?p=624#comment-298</guid>
		<description>&lt;p&gt;You are right; code size doesn&#039;t &lt;em&gt;have&lt;/em&gt; to increase if you&#039;re willing to forego copy elision for rvalues.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>You are right; code size doesn&#8217;t <em>have</em> to increase if you&#8217;re willing to forego copy elision for rvalues.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

