302 lines
11 KiB
Markdown
302 lines
11 KiB
Markdown
[class.copy.ctor]
|
||
|
||
# 11 Classes [[class]](./#class)
|
||
|
||
## 11.4 Class members [[class.mem]](class.mem#class.copy.ctor)
|
||
|
||
### 11.4.5 Constructors [[class.ctor]](class.ctor#class.copy.ctor)
|
||
|
||
#### 11.4.5.3 Copy/move constructors [class.copy.ctor]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1477)
|
||
|
||
A non-template constructor for classX is
|
||
a
|
||
copy
|
||
constructor if its first parameter is of typeX&,const X&,volatile X& orconst volatile X&,
|
||
and either there are no other parameters
|
||
or else all other parameters have default arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#1.sentence-1)
|
||
|
||
[*Example [1](#example-1)*:
|
||
|
||
X::X(const X&) andX::X(X&,int=1) are copy constructors[.](#1.sentence-2)
|
||
|
||
struct X { X(int);
|
||
X(const X&, int = 1);};
|
||
X a(1); // calls X(int); X b(a, 0); // calls X(const X&, int); X c = b; // calls X(const X&, int); â *end example*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1512)
|
||
|
||
A non-template constructor for class X is a move constructor if its
|
||
first parameter is of type X&&, const X&&,volatile X&&, or const volatile X&&, and either there are
|
||
no other parameters or else all other parameters have default
|
||
arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#2.sentence-1)
|
||
|
||
[*Example [2](#example-2)*:
|
||
|
||
Y::Y(Y&&) is a move constructor[.](#2.sentence-2)
|
||
|
||
struct Y { Y(const Y&);
|
||
Y(Y&&);};extern Y f(int);
|
||
Y d(f(1)); // calls Y(Y&&) Y e = d; // calls Y(const Y&) â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1531)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
All forms of copy/move constructor can be declared for a class[.](#3.sentence-1)
|
||
|
||
[*Example [3](#example-3)*: struct X { X(const X&);
|
||
X(X&); // OK X(X&&);
|
||
X(const X&&); // OK, but possibly not sensible}; â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1546)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
If a classX only has a copy constructor with a parameter of typeX&,
|
||
an initializer of typeconstX orvolatileX cannot initialize an object of typecv X[.](#4.sentence-1)
|
||
|
||
[*Example [4](#example-4)*: struct X { X(); // default constructor X(X&); // copy constructor with a non-const parameter};const X cx;
|
||
X x = cx; // error: X::X(X&) cannot copy cx into x â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1572)
|
||
|
||
A declaration of a constructor for a classX is ill-formed if its first parameter is of typecv X and either there are no other parameters or else all other parameters have
|
||
default arguments[.](#5.sentence-1)
|
||
|
||
A member function template is never instantiated to
|
||
produce such a constructor signature[.](#5.sentence-2)
|
||
|
||
[*Example [5](#example-5)*: struct S {template<typename T> S(T);
|
||
S();};
|
||
|
||
S g;
|
||
|
||
void h() { S a(g); // does not instantiate the member template to produce S::S<S>(S);// uses the implicitly declared copy constructor} â *end example*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1597)
|
||
|
||
If the class definition does not explicitly declare a copy constructor,
|
||
a non-explicit one is declared [*implicitly*](#def:constructor,copy,implicitly_declared "11.4.5.3 Copy/move constructors [class.copy.ctor]")[.](#6.sentence-1)
|
||
|
||
If the class definition declares a move
|
||
constructor or move assignment operator, the implicitly declared copy
|
||
constructor is defined as deleted; otherwise, it is
|
||
defaulted ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions"))[.](#6.sentence-2)
|
||
|
||
The latter case is deprecated if the class has a user-declared copy assignment
|
||
operator or a user-declared destructor ([[depr.impldec]](depr.impldec "D.6 Implicit declaration of copy functions"))[.](#6.sentence-3)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1607)
|
||
|
||
The implicitly-declared copy constructor for a classX will have the formX::X(const X&) if each potentially constructed subobject of a class typeM (or array thereof)
|
||
has a copy constructor whose first parameter is of typeconstM& orconstvolatileM&[.](#7.sentence-1)[89](#footnote-89 "This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue; see [diff.class].")
|
||
|
||
Otherwise, the implicitly-declared copy constructor will have the formX::X(X&)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1636)
|
||
|
||
If the definition of a class X does not explicitly declare
|
||
a move constructor, a non-explicit one will be
|
||
implicitly declared as defaulted if and only if
|
||
|
||
- [(8.1)](#8.1)
|
||
|
||
X does not have a user-declared copy constructor,
|
||
|
||
- [(8.2)](#8.2)
|
||
|
||
X does not have a user-declared copy assignment operator,
|
||
|
||
- [(8.3)](#8.3)
|
||
|
||
X does not have a user-declared move assignment operator, and
|
||
|
||
- [(8.4)](#8.4)
|
||
|
||
X does not have a user-declared destructor[.](#8.sentence-1)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
When the move constructor is not implicitly declared or explicitly supplied,
|
||
expressions that otherwise would have invoked the move constructor might instead invoke
|
||
a copy constructor[.](#8.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1661)
|
||
|
||
The implicitly-declared move constructor for class X will have the formX::X(X&&)
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1667)
|
||
|
||
An implicitly-declared copy/move constructor is an
|
||
inline public member of its class[.](#10.sentence-1)
|
||
|
||
A defaulted copy/move constructor for a class X is defined as deleted ([[dcl.fct.def.delete]](dcl.fct.def.delete "9.6.3 Deleted definitions")) if X has:
|
||
|
||
- [(10.1)](#10.1)
|
||
|
||
a potentially constructed subobject of type M (or possibly multidimensional array thereof) for which
|
||
overload resolution ([[over.match]](over.match "12.2 Overload resolution")), as applied to find M's corresponding constructor,
|
||
either does not result in a usable candidate ([[over.match.general]](over.match.general "12.2.1 General")) or,
|
||
in the case of a variant member, selects a non-trivial function,
|
||
|
||
- [(10.2)](#10.2)
|
||
|
||
any potentially constructed subobject of
|
||
class type M (or possibly multidimensional array thereof)
|
||
where M has
|
||
a destructor that is deleted or inaccessible from the defaulted
|
||
constructor, or,
|
||
|
||
- [(10.3)](#10.3)
|
||
|
||
for the copy constructor, a non-static data member of rvalue reference type[.](#10.sentence-2)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
A defaulted move constructor that is defined as deleted is ignored by overload
|
||
resolution ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#10.sentence-3)
|
||
|
||
Such a constructor would otherwise interfere with initialization from
|
||
an rvalue which can use the copy constructor instead[.](#10.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1696)
|
||
|
||
A copy/move constructor for classX is
|
||
trivial
|
||
if it is not user-provided and if
|
||
|
||
- [(11.1)](#11.1)
|
||
|
||
classX has no virtual functions ([[class.virtual]](class.virtual "11.7.3 Virtual functions"))
|
||
and no virtual base classes ([[class.mi]](class.mi "11.7.2 Multiple base classes")), and
|
||
|
||
- [(11.2)](#11.2)
|
||
|
||
the constructor selected to copy/move each direct base class subobject is trivial, and
|
||
|
||
- [(11.3)](#11.3)
|
||
|
||
for each non-static data member ofX that is of class type (or array thereof),
|
||
the constructor selected to copy/move that member is trivial;
|
||
|
||
otherwise the copy/move constructor is[*non-trivial*](#def:constructor,copy,nontrivial "11.4.5.3 Copy/move constructors [class.copy.ctor]")[.](#11.sentence-1)
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1724)
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
The copy/move constructor is implicitly defined even if the implementation elided
|
||
its odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule"), [[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#12.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
If an implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")) constructor would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers")),
|
||
the implicitly-defined
|
||
constructor is constexpr[.](#12.sentence-2)
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1733)
|
||
|
||
Before the defaulted copy/move constructor for a class is
|
||
implicitly defined,
|
||
all non-user-provided copy/move constructors for its
|
||
potentially constructed subobjects
|
||
are implicitly defined[.](#13.sentence-1)
|
||
|
||
[*Note [6](#note-6)*:
|
||
|
||
An implicitly-declared copy/move constructor has an
|
||
implied exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#13.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1744)
|
||
|
||
The implicitly-defined copy/move constructor for a non-union classX performs a memberwise copy/move of its bases and members[.](#14.sentence-1)
|
||
|
||
[*Note [7](#note-7)*:
|
||
|
||
Default member initializers of non-static data members are ignored[.](#14.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
The order of initialization is the same as the order of initialization of bases
|
||
and members in a user-defined constructor (see [[class.base.init]](class.base.init "11.9.3 Initializing bases and members"))[.](#14.sentence-3)
|
||
|
||
Let x be either the parameter of the constructor or, for the move constructor, an
|
||
xvalue referring to the parameter[.](#14.sentence-4)
|
||
|
||
Each base or non-static data member
|
||
is copied/moved in the manner appropriate to its type:
|
||
|
||
- [(14.1)](#14.1)
|
||
|
||
if the member is an array, each element is
|
||
direct-initialized with the corresponding subobject of x;
|
||
|
||
- [(14.2)](#14.2)
|
||
|
||
if a member m has rvalue reference type T&&, it is direct-initialized withstatic_cast<T&&>(x.m);
|
||
|
||
- [(14.3)](#14.3)
|
||
|
||
otherwise, the base or member is direct-initialized with the corresponding base or member of x[.](#14.sentence-5)
|
||
|
||
Virtual base class subobjects shall be initialized only once by
|
||
the implicitly-defined copy/move constructor (see [[class.base.init]](class.base.init "11.9.3 Initializing bases and members"))[.](#14.sentence-6)
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1774)
|
||
|
||
The implicitly-defined copy/move constructor for a unionX copies the object representation ([[basic.types.general]](basic.types.general#term.object.representation "6.9.1 General")) of X[.](#15.sentence-1)
|
||
|
||
For each object nested within ([[intro.object]](intro.object "6.8.2 Object model"))
|
||
the object that is the source of the copy,
|
||
a corresponding object o nested within the destination
|
||
is identified (if the object is a subobject) or created (otherwise),
|
||
and the lifetime of o begins before the copy is performed[.](#15.sentence-2)
|
||
|
||
[89)](#footnote-89)[89)](#footnoteref-89)
|
||
|
||
This implies that the reference parameter of the
|
||
implicitly-declared copy constructor
|
||
cannot bind to avolatile lvalue; see [[diff.class]](diff.class "C.7.7 [class]: classes")[.](#footnote-89.sentence-1)
|