This document is a revision of N2377 "Extending Move Semantics To *this (revised wording)", following suggestions of the Core Working Group. Rationale for the proposal is presented in document N1821. Notable changes from N2377 are:
Following refers to the current draft
N2315.
Deletions are marked like this and additions are marked like this.
1.3.11
|
[defns.signature] |
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 cv-qualifiers (if any) and the ref-qualifiers (if any) 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). [ Note: Signatures are used as a basis for name mangling and linking. —end note ]
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 or a ref-qualifier
(or both) 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 (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.
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.
13.1 Overloadable declarations |
[over.load] |
2 Certain function declarations cannot be overloaded:
class X { static void f(); void f(); // ill-formed void f() const; // ill-formed void f() const volatile; // ill-formed void g(); void g() const; // OK: no static g void g() const volatile; // OK: no static g };
- end example]class Y { void h() &; void h() const &; // OK void h() &&; // OK, all declarations h() have a ref-qualifier void i() &; void i() const; // ill-formed, prior declaration i() has a ref-qualifier };
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, 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:
--- end example] or, if not that,int f(const int *); int f(int *); int i; int j = f(&i); // calls f(int *)
--- end example] or, if not that,int i; int f(); int g(const int&); int g(const int&&); int j = g(i); // calls g(const int&) int k = g(f()) // calls g(const int&&)struct A { A& operator<<(int); };struct A { A& operator<<(int); void p() &; void p() &&; }; A& operator<<(A&&, char); A() << 1; // calls A::operator<<(int) A() << ’c’; // calls operator<<(A&&, char) A a; a << 1; // calls A::operator<<(int) a << ’c’; // calls operator<<(A&&, char) A().p(); // calls A::p()&& a.p(); // calls A::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.