Title
Reference members and generated copy constructors
Status
c++11
Section
11.4.5.3 [class.copy.ctor]
Submitter
Steve Adamczyk

Created on 2010-03-11.00:00:00 last changed 130 months ago

Messages

Date: 2010-11-15.00:00:00

[Voted into the WP at the November, 2010 meeting.]

Date: 2010-10-15.00:00:00

Proposed resolution (October, 2010):

  1. Change 11.4.5.3 [class.copy.ctor] paragraph 12 as follows:

  2. An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move constructor for a class X is defined as deleted (9.5.3 [dcl.fct.def.delete]) if X has:

    • a variant member with a non-trivial corresponding constructor and X is a union-like class,

    • a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (12.2 [over.match]), as applied to M's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor, or

    • a direct or virtual base class B that cannot be copied/moved because overload resolution (12.2 [over.match]), as applied to B's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor, or

    • for the copy constructor, a non-static data member of rvalue reference type, or

    • for the move constructor, a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.

  3. Change 11.4.5.3 [class.copy.ctor] paragraph 16 as follows:

  4. The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its subobjects bases and members. [Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 11.9.3 [class.base.init]. —end note] The order of copying initialization is the same as the order of initialization of bases and members in a user-defined constructor (see 11.9.3 [class.base.init]). Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter. Each subobject base or non-static data member is copied/moved in the manner appropriate to its type:

    • if the subobject is of class type, the copy constructor for the class is used;

    • if the subobject member is an array, each element is copied, in the manner appropriate to the element type direct-initialized with the corresponding subobject of x;

    • if a member m has rvalue reference type T&&, it is direct-initialized with static_cast<T&&>(x.m);

    • otherwise, the base or member is direct-initialized with the corresponding base or member of x.

    • if the subobject is of scalar type, the built-in assignment operator is used.

    Virtual base class subobjects shall be copied initialized only once by the implicitly-defined copy/move constructor (see 11.9.3 [class.base.init]).

  5. Delete 11.4.5.3 [class.copy.ctor] paragraph 17:

  6. The implicitly-defined move constructor for a non-union class X performs a memberwise move of its subobjects. [Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 11.9.3 [class.base.init]. —end note] The order of moving is the same as the order of initialization of bases and members in a user-defined constructor (see 11.9.3 [class.base.init]). Given a parameter named x, each base or non-static data member is moved in the manner appropriate to its type:

    • a named member m of reference or class type T is direct-initialized with the expression static_cast<T&&>(x.m);

    • a base class B is direct-initialized with the expression static_cast<B&&>(x);

    • an array is initialized by moving each element in the manner appropriate to the element type;

    • a scalar type is initialized with the built-in assignment operator.

    Virtual base class subobjects shall be moved only once by the implicitly-defined move constructor (see 11.9.3 [class.base.init]).

  7. Change 11.4.5.3 [class.copy.ctor] paragraph 18 as follows:

  8. The implicitly-defined copy/move constructor for a union X copies the object representation (6.8 [basic.types]) of X.
  9. Change 11.4.5.3 [class.copy.ctor] paragraph 28 as follows:

  10. A copy/move assignment operator that is defaulted and not defined as deleted is implicitly defined when is assigned a value of its class type or a value of a class type derived from its class type it is used (6.3 [basic.def.odr]) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration.
  11. Change 11.4.5.3 [class.copy.ctor] paragraph 30 as follows:

  12. The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move 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. Let x be either the parameter of the function or, for the move assignment operator, an xvalue referring to the parameter. Each subobject is assigned in the manner appropriate to its type:

    • if the subobject is of class type, the copy assignment operator for the class is used as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes);

    • if the subobject is an array, each element is assigned, in the manner appropriate to the element type;

    • if the subobject is of scalar type, the built-in assignment operator is used.

    It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined 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] [Note: This does not apply to move assignment, as a defaulted move assignment operator is deleted if the class has virtual bases. —end note]

  13. Delete 11.4.5.3 [class.copy.ctor] paragraph 31:

  14. The implicitly-defined move 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. Given a parameter named x, each subobject is assigned in the manner appropriate to its type:

    • if the subobject is a named member c of class type C, as if by the expression this->c = static_cast<C&&>(x.c);

    • if the subobject is a direct base class B, as if by the expression this->B::operator=(static_cast<B&&>(x));

    • if the subobject is an array, each element is moved, in the manner appropriate to the element type;

    • if the subobject is of scalar type, the built-in assignment operator is used.

This resolution also resolves issues 1020, 1064 and 1066.

Date: 2022-02-18.07:47:23
N3092 comment US 62

The new wording describing generated copy constructors (11.4.5.3 [class.copy.ctor] paragraph 16) does not describe the initialization of members with reference type.

See also issue 992.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: dr -> fdis
2010-11-29 00:00:00adminsetmessages: + msg3187
2010-11-29 00:00:00adminsetstatus: tentatively ready -> dr
2010-10-18 00:00:00adminsetstatus: ready -> tentatively ready
2010-08-23 00:00:00adminsetmessages: + msg2795
2010-08-23 00:00:00adminsetstatus: open -> ready
2010-03-11 00:00:00admincreate