Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is in addition to Terry's answer.</p> <p>The reason we had to make <code>swap</code> functions in C++ prior to 0x is because the general free-function <code>std::swap</code> was less efficient (and less versatile) than it could be. It made a copy of a parameter, then had two re-assignments, then released the essentially wasted copy. Making a copy of a heavy-weight class is a waste of time, when we as programmers know all we really need to do is swap the internal pointers and whatnot.</p> <p>However, rvalue-references relieve this completely. In C++0x, <code>swap</code> is implemented as:</p> <pre><code>template &lt;typename T&gt; void swap(T&amp; x, T&amp; y) { T temp(std::move(x)); x = std::move(y); y = std::move(temp); } </code></pre> <p>This makes much more sense. Instead of copying data around, we are merely moving data around. This even allows non-copyable types, like streams, to be swapped. The draft of the C++0x standard states that in order for types to be swapped with <code>std::swap</code>, they must be rvalue constructable, and rvalue assignable (obviously).</p> <p>This version of <code>swap</code> will essentially do what any custom written swap function would do. Consider a class we'd normally write <code>swap</code> for (such as this "dumb" vector):</p> <pre><code>struct dumb_vector { int* pi; // lots of allocated ints // constructors, copy-constructors, move-constructors // copy-assignment, move-assignment }; </code></pre> <p>Previously, <code>swap</code> would make a redundant copy of all our data, before discarding it later. Our custom <code>swap</code> function would just swap the pointer, but can be clumsy to use in some cases. In C++0x, moving achieves the same end result. Calling <code>std::swap</code> would generate:</p> <pre><code>dumb_vector temp(std::move(x)); x = std::move(y); y = std::move(temp); </code></pre> <p>Which translates to:</p> <pre><code>dumb_vector temp; temp.pi = x.pi; x.pi = 0; // temp(std::move(x)); x.pi = y.pi; y.pi = 0; // x = std::move(y); y.pi = temp.pi; temp.pi = 0; // y = std::move(temp); </code></pre> <p>The compiler will of course get rid of redundant assignment's, leaving:</p> <pre><code>int* temp = x.pi; x.pi = y.pi; y.pi = temp; </code></pre> <p>Which is <em>exactly</em> what our custom <code>swap</code> would have made in the first place. So while prior to C++0x I would agree with your suggestion, custom <code>swap</code>'s aren't really necessary anymore, with the introduction of rvalue-references. <code>std::swap</code> will work perfectly in any class that implements move functions.</p> <p>In fact, I'd argue implementing a <code>swap</code> function should become bad practice. Any class that would need a <code>swap</code> function would also need rvalue functions. But in that case, there is simply no need for the clutter of a custom <code>swap</code>. Code size does increase (two ravlue functions versus one <code>swap</code>), but rvalue-references don't just apply for swapping, leaving us with a positive trade off. (Overall faster code, cleaner interface, slightly more code, no more <code>swap</code> ADL hassle.)</p> <p>As for whether or not we can <code>default</code> rvalue functions, I don't know. I'll look it up later or maybe someone else can chime in, but that would sure be helpful. :) </p> <p>Even so, it makes sense to allow <code>default</code> rvalue functions instead of <code>swap</code>. So in essence, as long as they allow <code>= default</code> rvalue functions, your request has already been made. :)</p> <p>EDIT: I did a bit of searching, and the proposal for <code>= default</code> move was proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2583.html" rel="noreferrer"><code>n2583</code></a>. According to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2869.html" rel="noreferrer">this</a> (which I don't know how to read very well), it was "moved back." It is listed under the section titled "Not ready for C++0x, but open to resubmit in future ". So looks like it won't be part of C++0x, but may be added later.</p> <p>Somewhat disappointing. :(</p> <p>EDIT 2: Looking around a bit more, I found this: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2953.html" rel="noreferrer">Defining Move Special Member Functions</a> which is much more recent, and does look like we can default <code>move</code>. Yay!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload