<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>Default Swap Functions</title>
</head>

<body>
<h1>Default Swap Functions</h1>

<p>ISO/IEC JTC1 SC22 WG21 N2584 = 08-0094 - 2008-03-16

<p>Lawrence Crowl, Lawrence@Crowl.org, crowl@google.com

<h2>Introduction</h2>

<p>
Exploiting move semantics and interacting with standard containers
may require writing class-specific swap functions.
As these functions have significant common implementations,
the ability to specify default implementations for them
would improve programmer productivity.
</p>

<h2>Proposal</h2>

<p>
We propose to extend the <code>=default</code> syntax of
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2346.htm">N2346
Defaulted and Deleted Functions</a>
to specify a default implementation.
</p>

<p>
Semantically, the default implementation of the swap member function
is a recursive swap of its subobjects.
</p>

<p>
For example,
</p>
<blockquote><pre><code>
struct Derived
:
    public Base
{
    std::vector&lt;int&gt; vec;
    std::string name;

    void swap(Derived&amp;&amp; x)
    {
        using std::swap;
        swap(static_cast&lt;Base&amp;&gt;(*this), static_cast&lt;Base&amp;&gt;(x));
        swap(vec, x.vec);
        swap(name, x.name);
    }
};
</code></pre></blockquote>

<p>
In addition, a definition of a namespace-scope swap function
may be necessary or desireable.
The corresponding default implementation is:
</p>
<blockquote><pre><code>
void swap(Derived&amp; x, Derived&amp; y) { x.swap(y); }
</code></pre></blockquote>

<p>
Howard Hinnant voices the following concern:
</p>
<blockquote>
<p>
I want to be careful that we don't break current code
that we may not be expecting:
such as member <code>swap</code>
calls <code>std::swap</code> for
<code>*this</code>.
I don't think we've done that yet.
</p>
</blockquote>

<p>
Note, however, that such code would be redundant
with the current use of swap in the standard library.
</p>

<h2>Wording</h2>

<p>
The proposed wording shows changes
from an editing draft preliminary to the March 2008 mailing.
The base text does not form an officially accepted draft.
Earlier drafts have slightly different text.
</p>

<p>Note that the edits to section 8.4, 8.4.1, and 8.4.2
are identical in this paper and in
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2583.html">N2583
Default Move Functions</a>.

<h3>8.4 Function definitions [dcl.fct.def]</h3>

<p>
End the section after paragraph 8.
</p>

<h3>8.4.1 Explicitly-defaulted definitions [dcl.fct.def.default]</h3>

<p>
Add a new section comprising paragraph 9
of the old 8.4 Function definitions [dcl.fct.def].
</p>

<p>
Split the paragraph into three paragraphs,
with the first paragraph containing the introductory sentence,
the second paragraph containing the special member discussion,
and the third paragraph containing the note and example.
</p>

<p>
Edit the resulting second paragraph as follows.
</p>
<blockquote>
<p>
<del>Only special</del>
Special member functions may be explicitly defaulted,
and the implementation shall define them
as if they had implicit definitions (12.1, 12.4, 12.8).
A special member function
that would be implicitly defined as deleted
shall not be explicitly defaulted.
A special member function is <dfn>user-provided</dfn>
if it is user-declared
and not explicitly defaulted on its first declaration.
A user-provided explicitly-defaulted function
is defined at the point where it is explicitly defaulted.
</p>
</blockquote>

<h3>8.4.1.2 Swap function defaults [dcl.fct.def.swap]</h3>

<p>
Add a new section with the following paragraphs.
</p>

<blockquote>

<p>
A swap non-member function
(20.1.1 [utility.arg.requirements])
has no implicit default,
but may be explicitly defaulted.
The default definition
shall invoke the swap member function on the first argument,
passing it the second argument.
</p>

<p>
[<i>Example:</i>
The definition
</p>
<blockquote><pre><code>
void swap(T&amp; x, T&amp; y) = default;
</code></pre></blockquote>
<p>
is equivalent to
</p>
<blockquote><pre><code>
void swap(T&amp; x, T&amp; y) { x.swap(y); }
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>

<p>
A swap member function has no implicit default,
but may be explicitly defaulted.
The default definition
shall swap its bases and variables
from the corresponding bases and variables
of the swap member function parameter.
</p>

<p>
[<i>Example:</i>
Given the class definition
</p>
<blockquote><pre><code>
struct Derived : public Base {
    std::vector&lt;int&gt; vec;
    std::string name;
    void swap(Derived&amp; x);
};
</code></pre></blockquote>
<p>
the member function definition
</p>
<blockquote><pre><code>
void Derived::swap(Derived&amp; x) = default;
</code></pre></blockquote>
<p>
is equivalent to
</p>
<blockquote><pre><code>
void Derived::swap(Derived&amp;&amp; x) {
    using std::swap;
    swap(static_cast&lt;Base&amp;&gt;(*this), static_cast&lt;Base&amp;&gt;(x));
    swap(vec, x.vec);
    swap(name, x.name);
}
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>

<p>
If the default implementation of a swap member function
would swap a reference variable,
the use of the swap member function default is ill-formed.
</p>

</blockquote>

<h3>8.4.2 Deleted definitions [dcl.fct.def.delete]</h3>

<p>
Add a new section comprising paragraph 10
of the old 8.4 Function definitions [dcl.fct.def].
</p>

</body>
</html>
