This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Voted into the WP at the November, 2010 meeting.]
N3092 comment US 62The 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.
Proposed resolution (October, 2010):
Change 11.4.5.3 [class.copy.ctor] paragraph 12 as follows:
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.
Change 11.4.5.3 [class.copy.ctor] paragraph 16 as follows:
The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its
subobjectsbases 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 ofcopyinginitialization 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. Eachsubobjectbase 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
subobjectmember is an array, each element iscopied, in the manner appropriate to the element typedirect-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
copiedinitialized only once by the implicitly-defined copy/move constructor (see 11.9.3 [class.base.init]).
Delete 11.4.5.3 [class.copy.ctor] paragraph 17:
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]).
Change 11.4.5.3 [class.copy.ctor] paragraph 18 as follows:
The implicitly-defined copy/move constructor for a union X copies the object representation (6.8 [basic.types]) of X.
Change 11.4.5.3 [class.copy.ctor] paragraph 28 as follows:
A copy/move assignment operator that is defaulted and not defined as deleted is implicitly defined whenis assigned a value of its class type or a value of a class type derived from its class typeit 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.
Change 11.4.5.3 [class.copy.ctor] paragraph 30 as follows:
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 usedas 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]
Delete 11.4.5.3 [class.copy.ctor] paragraph 31:
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.