<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title>Extending Move Semantics To *this (revised wording)</title>
<style>
p {text-align:justify}
li {text-align:justify}
ins {color:#008040; text-decoration:underline}
del {color:#FF0000; text-decoration:line-through}
tbody {font-style: italic}
</style>
</head>

<body>

<h2 align="center">Extending move semantics to *this (revised wording)</h2>
<h3 align="center">Bronek Kozicki</h3>
&nbsp;<br />
&nbsp;<br />
<address>
	Document number: N2439 = 07-0309<br />
	Date: 2007-10-05<br />
	Reply-to: Bronek Kozicki <a href="mailto:brok@spamcop.net">brok@spamcop.net</a><br />
</address>
<br />
<h3>Purpose</h3>
<p>This document is a revision of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2377.htm">N2377 
&quot;Extending Move Semantics To *this (revised wording)&quot;</a>, following suggestions 
of the Core Working Group. Rationale for the proposal is presented in document
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm">N1821</a>. 
Notable changes from <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2377.htm">N2377</a> are:</p>
<ul>
	<li>changed proposed wording in <a href="#8.4p5">clause 8.4</a></li>
	<li>globally changed references to 9.3.1 to refer to 8.3.5 instead and removed 
	some</li>
	<li>new proposed wording in <a href="#1.3.11">clause 1.3.11</a> </li>
	<li>new example in <a href="#13.3.3.2b">clause 13.3.3.2</a> </li>
</ul>
<h3>Proposed wording (formal)</h3>
<p>Following refers to the current draft
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2315.pdf">N2315</a>. 
Deletions are marked like <del>this</del> and additions are marked like <ins>this</ins>.</p>
<br />
<table width="100%">
	<tbody>
	<tr>
		<td align="left"><a name="1.3.11"></a>
		<h3>1.3.11<br />
		signature</h3>
		</td>
		<td align="right">
		<h3>[defns.signature]</h3>
		</td>
	</tr>
</tbody>
</table>
<p>the name and the parameter-type-list (8.3.5) of a function, as well as the class 
or namespace of which it is a member. If a function or function template is a class 
member its signature additionally includes the <i>cv-qualifiers</i> (if any)
<ins>and the <i>ref-qualifiers</i> (if any)</ins> on the function or function template 
itself. The signature of a function template additionally includes its return type 
and its template parameter list. The signature of a function template specialization 
includes the signature of the template of which it is a specialization and its template 
arguments (whether explicitly specified or deduced). [ <i>Note</i>: Signatures are 
used as a basis for name mangling and linking. <i>end note</i> ]</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h2>Chapter 8 Declarators</h2>
		</td>
		<td align="right">
		<h2>[dcl.decl]</h2>
		</td>
	</tr>
</tbody>
</table>
<p><b>4</b> Declarators have the syntax</p>
<blockquote>
	<pre>
<i>declarator:
    direct-declarator
    ptr-operator declarator</i>

<i>direct-declarator:
    declarator-id
    direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq<sub>opt</sub> <ins>ref-qualifier<sub>opt</sub></ins> exception-specification<sub>opt</sub>
    direct-declarator [ constant-expression<sub>opt</sub> ]
    ( declarator )</i>

<i>ptr-operator:
    </i>*<i>cv-qualifier-seq<sub>opt</sub></i>
    &amp;
    &amp;&amp;
    ::<i><sub>opt</sub> nested-name-specifier</i> * <i>cv-qualifier-seq<sub>opt</sub></i>

<i>cv-qualifier-seq:
    cv-qualifier cv-qualifier-seq<sub>opt</sub></i>

<i>cv-qualifier:
    const
    volatile</i>

<ins><i>ref-qualifier:</i>
    &amp;
    &amp;&amp;</ins>
</pre>
	<p>...</p>
</blockquote>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>8.1 Type names</h3>
		</td>
		<td align="right">
		<h3>[dcl.name]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>1</b> To specify type conversions explicitly, and as an argument of <tt>sizeof</tt>,
<tt>new</tt>, or <tt>typeid</tt>, the name of a type shall be specified. This can 
be done with a <i>type-id</i>, which is syntactically a declaration for an object 
or function of that type that omits the name of the object or function.</p>
<blockquote>
	<pre>
<i>type-id:
    type-specifier-seq abstract-declarator<sub>opt</sub>
    
type-specifier-seq:
    type-specifier type-specifier-seq<sub>opt</sub>

abstract-declarator:
    ptr-operator abstract-declarator<sub>opt</sub>
    direct-abstract-declarator</i>
    ...
<i>direct-abstract-declarator:
    direct-abstract-declarator<sub>opt</sub>
        </i>( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> <ins>ref-qualifier<sub>opt</sub></ins> exception-specification<sub>opt</sub>
    direct-abstract-declarator<sub>opt</sub> </i>[<i>constant-expression<sub>opt</sub></i> ]
    ( <i>abstract-declarator</i> )
</pre>
</blockquote>
<p>It is possible to identify uniquely the location in the <i>abstract-declarator</i> 
where the identifier would appear if the construction were a declarator in a declaration. 
The named type is then the same as the type of the hypothetical identifier.</p>
<p>...</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>8.3.5 Functions</h3>
		</td>
		<td align="right">
		<h3>[dcl.fct]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>1</b> In a declaration <tt>T D</tt> where <tt>D</tt> has the form:</p>
<blockquote>
	<pre>
	D1 ( <i>parameter-declaration-clause</i> ) <i>cv-qualifier-seq<sub>opt</sub> <ins>ref-qualifier<sub>opt</sub></ins> exception-specification<sub>opt</sub></i></pre>
</blockquote>
<p>type of the contained declarator-id in the declaration <tt>T D1</tt> is &quot;<i>derived-declarator-type-list
<tt>T</tt></i>,&quot; the type of the <i>declarator-id</i> in <tt>D</tt> is &quot;<i>derived-declarator-type-list</i> 
function of (<i>parameter-declaration-clause</i>) <i>cv-qualifier-seq<sub>opt</sub>
<ins>ref-qualifier<sub>opt</sub></ins></i> returning T&quot;; a type of this form is 
a function type <sup>85)</sup>.</p>
<p>...</p>
<p><b>4</b> A <i>cv-qualifier-seq</i> shall only be part of the function type for 
a non-static member function, the function type to which a pointer to member refers, 
or the top-level function type of a function typedef declaration. The effect of 
a <i>cv-qualifier-seq</i> in a function declarator is not the same as adding cv-qualification 
on top of the function type. In the latter case, the cv-qualifiers are ignored. 
[<i>Example:</i> </p>
<blockquote>
	<pre>
typedef void F();
struct S {
	const F f;              //<i> OK: equivalent to:</i> void<i> </i>f();
};
</pre>
</blockquote>
<br />
<p><i>- end example</i>] . <ins>A <i>ref-qualifier</i> shall only be part of the 
function type for a non-static member function, the function type to which a pointer 
to member refers, or the top-level function type of a function typedef declaration.</ins> 
The return type, the parameter type list<ins>, the <i>ref-qualifier</i></ins> and 
the <i>cv-qualifier-seq</i>, but not the default arguments (8.3.6) or the exception 
specification (15.4), are part of the function type. [<i>Note:</i> function types 
are checked during the assignments and initializations of pointer-to-functions, 
reference-to-functions, and pointer-to-member-functions. <i>- end note</i> ]</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>8.4 Function definitions</h3>
		</td>
		<td align="right">
		<h3>[dcl.fct.def]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>2</b> The declarator in a <i>function-definition</i> shall have the form</p>
<blockquote>
	<pre>
	D1 ( <i>parameter-declaration-clause</i> ) cv-qualifier-seq<sub>opt</sub> <ins>ref-qualifier<sub>opt</sub></ins> exception-specification<sub>opt</sub>	</pre>
</blockquote>
<p>as described in 8.3.5. A function shall be defined only in namespace or class 
scope.</p>
<p><a name="8.4p5"></a><b>5</b> A <i>cv-qualifier-seq</i><ins> or a <i>ref-qualifier</i> 
(or both)</ins> can be part of a non-static member function declaration, non-static 
member function definition, or pointer to member function only <ins>(8.3.5)</ins>; 
see 9.3.2. <del>It is part of the function type.</del></p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>9.3.1 Nonstatic member functions</h3>
		</td>
		<td align="right">
		<h3>[class.mfct.non-static]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><ins><b>5</b> A non-static member function may be declared with a <i>ref-qualifier</i> 
(8.3.5), see 13.3.1.</ins></p>
<p><del>5</del><ins><b>6</b></ins> A non-static member function may be declared
<i>virtual</i> (10.3) or <i>pure virtual</i> (10.4).</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>10.3 Virtual functions</h3>
		</td>
		<td align="right">
		<h3>[class.virtual]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>2</b> If a virtual member function <tt>vf</tt> is declared in a class <tt>
Base</tt> and in a class <tt>Derived</tt>, derived directly or indirectly from
<tt>Base</tt>, a member function <tt>vf</tt> with the same name, parameter-type-list 
(8.3.5)<ins>, ref-qualifier (or absence of same)</ins>, and cv-qualification as
<tt>Base::vf</tt> is declared, then <tt>Derive d::vf</tt> is also virtual (whether 
or not it is so declared) and it <i>overrides</i><sup>97)</sup> <tt>Base::vf</tt>. 
For convenience we say that any virtual function overrides itself. Then in any well-formed 
class, for each virtual function declared in that class or any of its direct or 
indirect base classes there is a unique <i>final overrider</i> that overrides that 
function and every other overrider of that function. The rules for member lookup 
(10.2) are used to determine the final overrider for a virtual function in the scope 
of a derived class but ignoring names introduced by <i>using-declaration</i> s.</p>
<p>...</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>12.1 Constructors</h3>
		</td>
		<td align="right">
		<h3>[class.ctor]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>4</b> A constructor shall not be <tt>virtual</tt> (10.3) or <tt>static</tt> 
(9.4). A constructor can be invoked for a <tt>const</tt>, <tt>volatile</tt> or
<tt>const volatile</tt> object. A constructor shall not be declared <tt>const</tt>,
<tt>volatile</tt>, or <tt>const volatile</tt> (9.3.2). <tt>const</tt> and <tt>volatile</tt> 
semantics (7.1.5.1) are not applied on an object under construction. They come into 
effect when the constructor for the most derived object (1.8) ends. <ins>A constructor 
shall not be declared with a <i>ref-qualifier</i></ins>.</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>12.4 Destructors</h3>
		</td>
		<td align="right">
		<h3>[class.dtor]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>2</b> A destructor is used to destroy objects of its class type. A destructor 
takes no parameters, and no return type can be specified for it (not even <tt>void</tt>). 
The address of a destructor shall not be taken. A destructor shall not be <tt>static</tt>. 
A destructor can be invoked for a <tt>const</tt>, <tt>volatile</tt> or <tt>const 
volatile</tt> object. A destructor shall not be declared <tt>const</tt>, <tt>volatile</tt> 
or <tt>const volatile</tt> (9.3.2). <tt>const</tt> and <tt>volatile</tt> semantics 
(7.1.5.1) are not applied on an object under destruction. They stop being in effect 
when the destructor for the most derived object (1.8) starts. <ins>A destructor 
shall not be declared with a <i>ref-qualifier</i></ins>.</p>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>13.1 Overloadable declarations</h3>
		</td>
		<td align="right">
		<h3>[over.load]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>2</b> Certain function declarations cannot be overloaded: </p>
<ul>
	<li>Function declarations that differ only in the return type cannot be overloaded.
	</li>
</ul>
<ul>
	<li>Member function declarations with the same name and the same parameter types 
	cannot be overloaded if any of them is a <tt>static</tt> member function declaration 
	(9.4). Likewise, member function template declarations with the same name, the 
	same parameter-type-list, and the same template parameter lists cannot be overloaded 
	if any of them is a <tt>static</tt> member function template declaration. The 
	types of the implicit object parameters constructed for the member functions 
	for the purpose of overload resolution (13.3.1) are not considered when comparing 
	parameter-type-lists for enforcement of this rule. In contrast, if there is 
	no <tt>static</tt> member function declaration among a set of member function 
	declarations with the same name and the same parameter-type-list, then these 
	member function declarations can be overloaded if they differ in the type of 
	their implicit object parameter. [ <i>Example:</i> the following illustrates 
	this distinction:
	<blockquote>
		<pre>class X {
    static void f();
    void f();                   //<i>   ill-formed</i>
    void f() const;             //<i>   ill-formed</i>
    void f() const volatile;    //<i>   ill-formed</i>
    void g();
    void g() const;             //<i>  OK: no static </i>g
    void g() const volatile;    //<i>  OK: no static </i>g
};
</pre>
	</blockquote>
	<br />
	<i>- end example</i>] </li>
</ul>
<ul>
	<ins>
	<li>Member function declarations with the same name and the same parameter-type-list, 
	as well as member function template declarations with the same name, the same 
	parameter-type-list, and the same template parameter lists, cannot be overloaded 
	if any of them, but not all, have a <i>ref-qualifier</i> (8.3.5). [ <i>Example:</i>
	</li></ins><li>
	<blockquote>
		<ins></ins>
		<pre><ins>class Y {
    void h() &amp;;
    void h() const &amp;; // OK
    void h() &amp;&amp;;      // OK<i>, all declarations </i>h()<i> have a ref-qualifier</i>  
    void i() &amp;;
    void i() const;   // <i>ill-formed, prior declaration </i>i()<i> has a ref-qualifier</i>
};
</ins></pre>
		<ins></ins>
	</blockquote>
	<ins><i>- end example</i>] </ins><li></li>
	<ins></ins></li>
</ul>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>13.3.1 Candidate functions and argument lists</h3>
		</td>
		<td align="right">
		<h3>[over.match.funcs]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>4</b> For non-static member functions, the type of the implicit object parameter 
is <del>&quot;reference to cv X&quot;</del></p>
<ul>
	<ins>
	<li>&quot;lvalue-reference to <i>cv</i> <tt>X</tt>&quot; for functions declared without 
	a <i>ref-qualifier</i> or with the <tt>&amp;</tt> <i>ref-qualifier</i> </li>
	<li>&quot;rvalue-reference to <i>cv</i> <tt>X</tt>&quot; for functions declared with the
	<tt>&amp;&amp;</tt> <i>ref-qualifier</i> </li>
	</ins>
</ul>
<p>where <tt>X</tt> is the class of which the function is a member and <i>cv</i> 
is the cv-qualification on the member function declaration. [<i>Example:</i> for 
a <tt>const</tt> member function of class <tt>X</tt>, the extra parameter is assumed 
to have type &quot;reference to <tt>const X</tt>&quot;. <i>- end example</i> ] For conversion 
functions, the function is considered to be a member of the class of the implicit 
object argument for the purpose of defining the type of the implicit object parameter. 
For non-conversion functions introduced by a <i>using-declaration</i> into a derived 
class, the function is considered to be a member of the derived class for the purpose 
of defining the type of the implicit object parameter. For static member functions, 
the implicit object parameter is considered to match any object (since if the function 
is selected, the object is discarded). [<i>Note:</i> no actual type is established 
for the implicit object parameter of a static member function, and no attempt will 
be made to determine a conversion sequence for that parameter (13.3.3). <i>- end 
note</i>]</p>
<p><b>5</b> During overload resolution, the implied object argument is indistinguishable 
from other arguments. The implicit object parameter, however, retains its identity 
since conversions on the corresponding argument shall obey these additional rules:
</p>
<ul>
	<li>no temporary object can be introduced to hold the argument for the implicit 
	object parameter; and</li>
</ul>
<ul>
	<li>no user-defined conversions can be applied to achieve a type match with 
	it;<del> and</del></li>
</ul>
<p><ins>For non-static member functions declared without a <i>ref-qualifier</i>, 
an additional rule applies:</ins></p>
<ul>
	<li>even if the implicit object parameter is not <tt>const</tt>-qualified, an 
	rvalue temporary can be bound to the parameter as long as in all other respects 
	the temporary can be converted to the type of the implicit object parameter. 
	[ <i>Note:</i> The fact that such a temporary is an rvalue does not affect the 
	ranking of implicit conversion sequences (13.3.3.2). <i>- end note</i> ]
	</li>
</ul>
<table width="100%">
	<tbody>
	<tr>
		<td align="left">
		<h3>13.3.3.2 Ranking implicit conversion sequences</h3>
		</td>
		<td align="right">
		<h3>[over.ics.rank]</h3>
		</td>
	</tr>
</tbody>
</table>
<p><b>3</b> Two implicit conversion sequences of the same form are indistinguishable 
conversion sequences unless one of the following rules apply: </p>
<ul>
	<li><tt>S1</tt> and <tt>S2</tt> differ only in their qualification conversion 
	and yield similar types <tt>T1</tt> and <tt>T2</tt> (4.4), respectively, and 
	the cv-qualification signature of type <tt>T1</tt> is a proper subset of the 
	cv-qualification signature of type <tt>T2</tt>, and <tt>S1</tt> is not the deprecated 
	string literal array-to-pointer conversion (4.2). [<i>Example:</i>
	<blockquote>
		<pre>int f(const int *);
int f(int *);
int i;
int j = f(&amp;i);                       //  calls  f(int *)
</pre>
	</blockquote>
	--- <i>end example</i>] or, if not that, </li>
	<li><a name="13.3.3.2b"></a><tt>S1</tt> and <tt>S2</tt> are reference bindings 
	(8.5.3) and neither refers to an implicit object parameter <ins>of a non-static 
	member function declared without a <i>ref-qualifier</i></ins>, and either
	<tt>S1</tt> binds an lvalue reference to an lvalue and <tt>S2</tt> binds an 
	rvalue reference or <tt>S1</tt> binds an rvalue reference to an rvalue and
	<tt>S2</tt> binds an lvalue reference.<br />
	[<i>Example:</i><blockquote>
		<pre>int i;
int f();
int g(const int&amp;);
int g(const int&amp;&amp;);
int j = g(i);                 // calls g(const int&amp;)
int k = g(f())                // calls g(const int&amp;&amp;)

<del>struct A { A&amp; operator&lt;&lt;(int); };</del><ins>
struct A {
  A&amp; operator&lt;&lt;(int);
  void p() &amp;; 
  void p() &amp;&amp;;
};</ins>
A&amp; operator&lt;&lt;(A&amp;&amp;, char);
A() &lt;&lt; 1;                     // calls A::operator&lt;&lt;(int)
A() &lt;&lt; c;                   // calls operator&lt;&lt;(A&amp;&amp;, char)
A a;
a &lt;&lt; 1;                       // calls A::operator&lt;&lt;(int)
a &lt;&lt; c;                     // calls operator&lt;&lt;(A&amp;&amp;, char)
<ins>A().p();                      // calls A::p()&amp;&amp;</ins>
<ins>a.p();                        // calls A::p()&amp;</ins>
</pre>
	</blockquote>
	--- <i>end example</i>] or, if not that, </li>
</ul>
<p>...</p>
&nbsp;<br />
&nbsp;<br />
<h3>Acknowledgments</h3>
<p>Daveed Vandevoorde provided support when it was most needed, Howard Hinnant gave encouragement through all 
the stages of the proposal and provided partial wording, Jens Maurer helped to build final proposed wording.<p>
</body>

</html>