Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy aren't there compiler-generated swap() methods in C++0x?
    primarykey
    data
    text
    <p>C++ compilers automatically generate copy constructors and copy-assignment operators. Why not <code>swap</code> too?</p> <p>These days the preferred method for implementing the copy-assignment operator is the copy-and-swap idiom:</p> <pre><code>T&amp; operator=(const T&amp; other) { T copy(other); swap(copy); return *this; } </code></pre> <p>(<a href="http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/" rel="noreferrer">ignoring the copy-elision-friendly form that uses pass-by-value</a>).</p> <p>This idiom has the advantage of being transactional in the face of exceptions (assuming that the <code>swap</code> implementation does not throw). In contrast, the default compiler-generated copy-assignment operator recursively does copy-assignment on all base classes and data members, and that doesn't have the same exception-safety guarantees.</p> <p>Meanwhile, implementing <code>swap</code> methods manually is tedious and error-prone:</p> <ol> <li>To ensure that <code>swap</code> does not throw, it must be implemented for all non-POD members in the class and in base classes, in their non-POD members, etc.</li> <li>If a maintainer adds a new data member to a class, the maintainer must remember to modify that class's <code>swap</code> method. Failing to do so can introduce subtle bugs. Also, since <code>swap</code> is an ordinary method, compilers (at least none I know of) don't emit warnings if the <code>swap</code> implementation is incomplete.</li> </ol> <p>Wouldn't it be better if the compiler generated <code>swap</code> methods automatically? Then the implicit copy-assignment implementation could leverage it.</p> <p>The obvious answer probably is: the copy-and-swap idiom didn't exist when C++ was developed, and doing this now might break existing code.</p> <p>Still, maybe people could opt-in to letting the compiler generate <code>swap</code> using the same syntax that C++0x uses for controlling other implicit functions:</p> <pre><code>void swap() = default; </code></pre> <p>and then there could be rules:</p> <ol> <li>If there is a compiler-generated <code>swap</code> method, an implicit copy-assignment operator can be implemented using copy-and-swap.</li> <li>If there is no compiler-generated <code>swap</code> method, an implicit copy-assignment operator would be implemented as before (invoking copy-assigment on all base classes and on all members).</li> </ol> <p>Does anyone know if such (crazy?) things have been suggested to the C++ standards committee, and if so, what opinions committee members had?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COI've wondered the same thing a number of times, especially since `swap` is usually implemented in term of `swapping` all the data members anyway, so it's much like `copy` or `assignment` and the new `move` versions.
      singulars
    2. COIn C++0x, `swap` should be something along the lines of `template <typename T> void swap(T& x, T& y) { T temp(std::move(x)); x = std::move(y); y = std::move(temp); }` which will essentially do what any custom written swap functions would do. I agree with your question, but custom swaps aren't really necessary anymore, with the introduction of r-value references. `std::swap` will work great.
      singulars
    3. COI suspect the reason it's not in C++98 is that the only compiler-generated functions in C++ are there in order to make classes behave like C structs: you can declare them, destroy them and copy them. However useful a default `swap` or a default `operator<` might be (and both could be implemented by field-wise operations) the C++ standard wanted a minimum of default functions, so there's less to suppress if you don't want it. The C++0x `function = something` syntax could be a much better fit, since it's optional. You could in principle even have different options for safe and unsafe swaps.
      singulars
 

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