Jason Merrill, John Spicer
2010-03-12
N3079=10-0069

Redrafting: issues 667, 861, 990, 818

Introduction

This paper contains drafting for various core issues that were not in the pre-meeting mailing (818), or are slightly revised from what was in the pre-meeting mailing.
Issue 667
Issue 990
Issue 818
Issues 861, 919, 920

Issue 667 Proposed Resolution

8.4 [dcl.fct.def]:
Only special member functions may be explicitly defaulted. Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall define them as if they hadprovide implicit definitions for them (12.1 [class.ctor], 12.4 [class.dtor], 12.8 [class.copy]), which might mean defining them as deleted. A special member function that would be implicitly defined as deleted may be explicitly defaulted only on its first declaration, in which case it is defined as deleted. A special member function is user-provided 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; if such a function is implicitly defined as deleted, the program is ill-formed.
12.1 [class.ctor]/5:
... If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A default constructor is trivial if it is not user-provided (8.4) and if:

An implicitly-declared defaulted default constructor for class X is defined as deleted if:

A default constructor is trivial if it is neither user-provided nor deleted and if:

Otherwise, the default constructor is non-trivial.

A non-user-provided default constructor for a class that is defaulted and not defined as deleted is implicitly defined when it is used (3.2) to create an object of its class type (1.8), or when it is explicitly defaulted after its first declaration. The implicitly-defined or explicitly-defaulted default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined default constructor is constexpr. Before the non-user-provideddefaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members shall have been implicitly defined. [ Note: an implicitly-declared default constructor has an exception-specification (15.4). An explicitly-defaulted definition has no implicit exception-specification. --end note ]

12.4 [class.dtor]/3:
If a class has no user-declared destructor, a destructor is declared implicitly declared as defaulted (8.4). An implicitly-declared destructor is an inline public member of its class. If the class is a union-like class that has a variant member with a non-trivial destructor, an implicitly-declared destructor is defined as deleted (8.4). A destructor is trivial if it is not user-provided and if: An implicitly-declared defaulted destructor for a class X is defined as deleted if: A destructor is trivial if it is neither user-provided nor deleted and if: Otherwise, the destructor is non-trivial.

A non-user-provided destructor that is defaulted and not defined as deleted is implicitly defined when it is used to destroy an object of its class type (3.7), or when it is explicitly defaulted after its first declaration. A program is ill-formed if the class for which a destructor is implicitly defined or explicitly defaulted has:

Before the non-user-provideddefaulted destructor for a class is implicitly defined, all the non-user-definedprovided destructors for its base classes and its non-static data members shall have been implicitly defined. [ Note: an implicitly-declared destructor has an exception-specification (15.4). An explictly defaulted definition has no implicit exception-specification. -- end note ]
12.8 [class.copy]:
If the class definition does not explicitly declare a copy constructor, one is declared implicitly declared as defaulted (8.4).

....

An implicitly-declared copy constructor is an inline public member of its class. An implicitly-declareddefaulted copy constructor for a class X is defined as deleted if X has: A copy constructor for class X is trivial if it is notneither user-provided nor deleted (8.4) and if otherwise the copy constructor is non-trivial.

A non-user-provided copy constructor that is defaulted and not defined as deleted is implicitly defined if it is used to initialize an object of its class type from a copy of an object of its class type or of a class type derived from its class type [ Footnote .... ], or when it is explicitly defaulted after its first declaration. [ Note: the copy constructor is implicitly defined even if the implementation elided its use (12.2). -- end note ]

Before the non-user-provideddefaulted copy constructor for a class is implicitly defined, all non-user-provided copy constructors for its direct and virtual base classes and its non-static data members shall have been implicitly defined. [ Note: an implicitly-declared copy constructor has an exception-specification (15.4). An explicitly- defaulted definition has no implicit exception-specification. -- end note ]

The implicitly-defined or explicitly-defaulted copy constructor for a non-union class X performs a memberwise copy of its subobjects. [ Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 12.6.2. -- end note ] The order of copying is the same as the order of initialization of bases and members in a user-defined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:

Virtual base class subobjects shall be copied only once by the implicitly-defined copy constructor (see 12.6.2).

The implicitly-defined or explicitly-defaulted copy constructor for a union X copies the object representation (3.9) of X.

....

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly declared as defaulted (8.4).

....

An implicitly-declared copy assignment operator is an inline public member of its class. An implicitly-declareddefaulted copy assignment operator for class X is defined as deleted if X has:

Because a copy assignment operator is implicitly declared for a class if not declared by the user, a base class copy assignment operator is always hidden by the copy assignment operator of a derived class (13.5.3). A using-declaration (7.3.3) that brings in from a base class an assignment operator with a parameter type that could be that of a copy-assignment operator for the derived class is not considered an explicit declaration of a copy-assignment operator and does not suppress the implicit declaration of the derived class copy- assignment operator; the operator introduced by the using-declaration is hidden by the implicitly-declared copy-assignment operator in the derived class.

A copy assignment operator for class X is trivial if it is notneither user-provided nor deleted and if

otherwise the copy assignment operator is non-trivial.

A non-user-provided copy assignment operator that is defaulted and not defined as deleted is implicitly defined when an object of its class type is assigned a value of its class type or a value of a class type derived from its class type, or when it is explicitly defaulted after its first declaration.

Before the non-user-provideddefaulted copy assignment operator for a class is implicitly defined, all non-user-provided copy assignment operators for its direct base classes and its non-static data members shall have been implicitly defined. [ Note: an implicitly-declared copy assignment operator has an exception-specification (15.4). An explicitly-defaulted definition has no implicit exception-specification. -- end note ]

The implicitly-defined or explicitly-defaulted copy assignment operator for a non-union class X performs memberwise assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition. Each subobject is assigned in the manner appropriate to its type:

It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined or explicitly-defaulted copy assignment operator. [ Example:
      struct  V { };
      struct  A : virtual V { };
      struct  B : virtual V { };
      struct  C : B, A { };
It is unspecified whether the virtual base class subobject V is assigned twice by the implicitly-defined copy assignment operator for C. -- end example ]

The implicitly-defined or explicitly-defaulted copy assignment operator for a union X copies the object representation (3.9) of X.


Issue 990 Proposed Resolution

Change 8.5.4 [dcl.init.list] paragraph 3 as follows:
List-initialization of an object or reference of type T is defined as follows:

Issues 861, 919, 920 Proposed Resolution

Common text

7.3.1 [namespace.def]/9:
These properties are transitive: if a namespace N contains an inline namespace M, which in turn contains an inline namespace O, then the members of O can be used as though they were members of M or N. The transitive closure of all inline namespaces in N is the inline namespace set of N. The set of namespaces consisting of the innermost non-inline namespace enclosing an inline namespace O, together with any intervening inline namespaces, is the enclosing namespace set of O.

Issue 861

3.4.3.2 [namespace.qual]:
If the nested-name-specifier of a qualified-id nominates a namespace, the name specified after the nested-name-specifier is looked up in the scope of the namespace, except that the names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression occurs.

For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S'(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni nominated by using-directives in X and its inline namespace set.

Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), let S be the set of all declarations of m in X and in the transitive closure of all namespaces nominated by using-directives in X and its used namespaces, except that using-directives that nominate non-inline namespaces (7.3.1) are ignored in any namespace, including X, directly containing one or more declarations of m. No namespace is searched more than once in the lookup of a name. I if S(X,m) is the empty set, the program is ill-formed. Otherwise, if S(X,m) has exactly one member, or if the context of the reference is a using-declaration (7.3.3), S(X,m) is the required set of declarations of m. Otherwise if the use of m is not one that allows a unique declaration to be chosen from S(X,m), the program is ill-formed.

Issue 919

[class]/11:
If a class-head contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set ([namespace.def]) of that namespace (i.e., not merely(i.e., neither inherited nor introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration.
[namespace.qual]/6:
In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-id for the namespace member has the form
        nested-name-specifier unqualified-id
the unqualified-id shall name a member of the namespace designated by the nested-name-specifier, or of an element of the inline namespace set ([namespace.def]) of that namespace.

Issue 920

[dcl.meaning]/1:
... When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set ofwithin that scopenamespace (7.3.1)), and; the member shall not merely have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id.

Issue 818 Drafting

Function parameter packs in non-final positions

Modify 8.3.5 [dcl.fct] paragraph 13 as follows:

A function parameter pack, if present, shall occur at the end of the parameter-declaration-list.

Modify 14.9.2.1 paragraph 1 as follows:

For a function parameter pack that occurs at the end of the parameter-declaration-list , the type A of each remaining argument of the call is compared with the type P of the declarator-id of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. For a function parameter pack that does not occur at the end of the parameter-declaration-clause, the type of the parameter pack is a non-deduced context. [Note: A function parameter pack can only occur at the end of a parameter-declaration-list (8.3.5). --end note ]

Add a bullet to 14.9.2.5 [temp.deduct.type] paragraph 5:

The non-deduced contexts are:

...

  • A function parameter pack that does not occur at the end of the parameter-declaration-clause.