<!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 Move Functions</title>
</head>

<body>
<h1>Default Move Functions</h1>

<p>ISO/IEC JTC1 SC22 WG21 N2583 = 08-0093 - 2008-03-16

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

<h2>Introduction</h2>

<p>
Exploiting move semantics
requires writing a move constructor or a move assignment operator.
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 use 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 move constructor
is a recursive move construction of its subobjects.
In the event that there is no move constructor defined for a subobject,
the copy constructor will be used instead.
</p>

<p>
The default implementation of the move assignment operator
has the corresponding semantics.
</p>

<p>
For example,
</p>
<blockquote><pre><code>
class Derived
:
    public Base
{
    std::vector&lt;int&gt; vec;
    std::string name;
public:
    Derived(Derived&amp;&amp; x)
    :
        Base(static_cast&lt;Base&amp;&amp;&gt;(x)),
        vec(static_cast&lt;std::vector&lt;int&gt;&amp;&amp;&gt;(x.vec)),
        name(static_cast&lt;std::string&amp;&amp;&gt;(x.name))
    { }

    Derived&amp; operator=(Derived&amp;&amp; x)
    {
        Base::operator=(static_cast&lt;Base&amp;&amp;&gt;(x));
        vec  = static_cast&lt;std::vector&lt;int&gt;&amp;&amp;&gt;(x.vec);
        name = static_cast&lt;std::string&amp;&amp;&gt;(x.name);
        return *this;
    }
};
</code></pre></blockquote>

<p>
There seems to be no reason to require that
move constructors and move assignment operators be trivial,
and so we do not.
</p>

<p>
A item of insecurity
is the handling of pointer member variables.
The insecurity is that the ownership of the indirect object
is not readily visible in the source code,
and no one default will be appropriate in all cases.
The possible approaches are:
</p>

<ol>
<li>
Make the default move ill-formed,
requiring the programmer to be clear
about the handling of the pointer.
This approach is a burden to programmers
for which one of the other approaches is adequate.
However, this approach is upwards compatible
with the other approaches
and is thus the least risky approach.
</li>
<li>
Define the default move to copy pointer variables.
This approach leaves indirect objects with multiple references,
so freeing those objects becomes difficult.
Under this approach, fully default moves are equivalent to fully default copies.
This approach has the simplest normative text.
</li>
<li>
Define the default move to copy pointer variables
and null out the corresponding variable in the move argument.
This approach avoids multiple references for owned objects,
but may leave the argument object in a state not expected by the destructor.
The most likely action in a destructor
is to simply delete the pointer,
so nulling out a pointer variable
still leaves the object in an 'expected' state
for such destructors
because one may delete a null pointer.
This approach has the most fidelity to move semantics.
</li>
</ol>

<p>
The handling of reference member variables
has much the same issue,
except that pointer approach 3 (null parameter pointer member variables)
is not possible for references.
Thus, the reference approaches are:
</p>

<ol>
<li>
Make the default move ill-formed.
</li>
<li>
Define the default move to copy reference variables.
This approach is possible only for move construction,
as reference variables cannot be assigned.
</li>
</ol>

<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/n2584.html">N2584
Default Swap 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.1 Move function defaults [dcl.fct.def.move]</h3>

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

<blockquote>
<p>
A move constructor has no implicit default,
but may be explicitly defaulted.
The default definition
shall move construct its bases and variables,
with arguments statically cast to a rvalue references (8.3.2 [dcl.ref])
from the corresponding bases and variables
of the move constructor parameter.
In the event that a base or variable has no move constructor,
the copy constructor is used instead,
without the static cast.
</p>

<p>
A move assignment operator has no implicit default,
but may be explicitly defaulted.
The default definition
shall move assign its bases and variables,
with arguments statically cast to a rvalue references (8.3.2 [dcl.ref])
from the corresponding bases and variables
of the move assignment operator parameter.
In the event that a base or variable has no move assignment operator,
the copy assignment operator is used instead,
without the static cast.
</p>
</blockquote>

<p>
If pointer approach 1 is adopted,
add the following paragraph.
</p>

<blockquote>
<p>
If the default implementation of a move function
would move from a pointer variable,
the use of the move function default is ill-formed.
</p>
</blockquote>

<p>
If pointer approach 2 is adopted,
no additional text is needed.
</p>

<p>
If pointer approach 3 is adopted,
add the following paragraph.
</p>

<blockquote>
<p>
If the default implementation of a move function
moves from a pointer variable,
the implementation shall assign null to that pointer variable.
</p>
</blockquote>

<p>
If reference approach 1 is adopted,
add the following paragraph.
</p>

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

<p>
If reference approach 2 is adopted,
add the following paragraph.
</p>

<blockquote>
<p>
If the default implementation of a move assignment operator
would move to a reference variable,
the use of the move 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>

<h3>Unknown Sections</h3>

<p>
The working draft currently uses the term "move constructor"
but does not define the term.
It is unclear where to add the definition,
move constructors are not a special member function,
but construction is most completely described
in Chapter 12 Special member functions [special].
</p>

<blockquote>
<p>
A move constructor
is a constructor with a declaration of the form
</p>
<blockquote>
<p>
<var>classname</var><code>(</code><var>classname</var><code>&amp;&amp;);</code>
</p>
</blockquote>
</blockquote>

<p>
The same issue applies to move assignment operators.
</p>

<blockquote>
<p>
A move assignment operator
is an assignment operator with a declaration of the form
</p>
<blockquote>
<p>
<var>classname</var><code>&amp;
operator=(</code><var>classname</var><code>&amp;&amp;);</code>
</p>
</blockquote>
</blockquote>

</body>
</html>
