Extending move semantics to *this (revised wording)

Bronek Kozicki and Daveed Vandevoorde

 
 
Document number: N2377=07-0237
Date: 2007-08-03
Reply-to: Bronek Kozicki brok@spamcop.net

Purpose

This document is a revision of N1821 "Extending Move Semantics To *this (Revision 1)" . The aim of this paper is to fix flaws discovered in the formal wording proposed in N1821. This paper does not change semantics or syntax proposed in N1821. Instead, it merely strives to implement the intent of the original proposal.

Proposed wording (formal)

Following refers to the current draft N2315. Deletions are marked like this and additions are marked like this.


Chapter 8 Declarators

[dcl.decl]

4 Declarators have the syntax

declarator:
    direct-declarator
    ptr-operator declarator

direct-declarator:
    declarator-id
    direct-declarator ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt
    direct-declarator [ constant-expressionopt ]
    ( declarator )

ptr-operator:
    *cv-qualifier-seqopt
    &
    &&
    ::opt nested-name-specifier * cv-qualifier-seqopt

cv-qualifier-seq:
    cv-qualifier cv-qualifier-seqopt

cv-qualifier:
    const
    volatile

ref-qualifier:
    &
    &&

...

8.1 Type names

[dcl.name]

1 To specify type conversions explicitly, and as an argument of sizeof, new, or typeid, the name of a type shall be specified. This can be done with a type-id, which is syntactically a declaration for an object or function of that type that omits the name of the object or function.

type-id:
    type-specifier-seq abstract-declaratoropt
    
type-specifier-seq:
    type-specifier type-specifier-seqopt

abstract-declarator:
    ptr-operator abstract-declaratoropt
    direct-abstract-declarator
    ...
direct-abstract-declarator:
    direct-abstract-declaratoropt
        ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt
    direct-abstract-declaratoropt [constant-expressionopt ]
    ( abstract-declarator )

It is possible to identify uniquely the location in the abstract-declarator 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.

...

8.3.5 Functions

[dcl.fct]

1 In a declaration T D where D has the form:

	D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt

type of the contained declarator-id in the declaration T D1 is "derived-declarator-type-list T," the type of the declarator-id in D is "derived-declarator-type-list function of (parameter-declaration-clause) cv-qualifier-seqopt ref-qualifieropt returning T"; a type of this form is a function type 85).

...

4 A cv-qualifier-seq 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 cv-qualifier-seq 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. [Example:

typedef void F();
struct S {
	const F f;              // OK: equivalent to: void f();
};

- end example] . A ref-qualifier 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 return type, the parameter type list, the ref-qualifier and the cv-qualifier-seq, but not the default arguments (8.3.6) or the exception specification (15.4), are part of the function type. [Note: function types are checked during the assignments and initializations of pointer-to-functions, reference-to-functions, and pointer-to-member-functions. - end note ]

8.4 Function definitions

[dcl.fct.def]

2 The declarator in a function-definition shall have the form

	D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt	

as described in 8.3.5. A function shall be defined only in namespace or class scope.

5 A cv-qualifier-seq Both a cv-qualifier-seq and a ref-qualifier can be part of a non-static member function declaration, non-static member function definition, or pointer to member function only (8.3.5); see 9.3.2. It is part of the function type.

9.3.1 Nonstatic member functions

[class.mfct.non-static]

5 A non-static member function may be declared with a ref-qualifier (8.3.5), see 13.3.1.

56 A non-static member function may be declared virtual (10.3) or pure virtual (10.4).

10.3 Virtual functions

[class.virtual]

2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), ref-qualifier (9.3.1) (or absence of same), and cv-qualification as Base::vf is declared, then Derive d::vf is also virtual (whether or not it is so declared) and it overrides97) Base::vf. 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 final overrider 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 using-declaration s.

...

12.1 Constructors

[class.ctor]

4 A constructor shall not be virtual (10.3) or static (9.4). A constructor can be invoked for a const, volatile or const volatile object. A constructor shall not be declared const, volatile, or const volatile (9.3.2). const and volatile 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. A constructor shall not be declared with a ref-qualifier (9.3.1).

12.4 Destructors

[class.dtor]

2 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 void). The address of a destructor shall not be taken. A destructor shall not be static. A destructor can be invoked for a const, volatile or const volatile object. A destructor shall not be declared const, volatile or const volatile (9.3.2). const and volatile 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. A destructor shall not be declared with a ref-qualifier (9.3.1).

13.1 Overloadable declarations

[over.load]

2 Certain function declarations cannot be overloaded:

13.3.1 Candidate functions and argument lists

[over.match.funcs]

4 For non-static member functions, the type of the implicit object parameter is "reference to cv X"

where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [Example: for a const member function of class X, the extra parameter is assumed to have type "reference to const X". - end example ] 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 using-declaration 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). [Note: 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). - end note]

5 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:

For non-static member functions declared without a ref-qualifier (9.3.1), an additional rule applies:

13.3.3.2 Ranking implicit conversion sequences

[over.ics.rank]

3 Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules apply:

 
 

Acknowledgments

I wish to thank Jens Maurer for much needed reviews and corrections and Howard Hinnant for valuable input. Special thanks goes to my wife Malgosia for allowing me to work on this document.