Files
2025-10-25 03:02:53 +03:00

302 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.7Default 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.7Default 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.3Copy/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.6Function 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.6Implicit 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.3Deleted 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.2Overload 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.1General")) 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.2Overload resolution"), [[over.over]](over.over "12.3Address 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.3Virtual functions"))
and no virtual base classes ([[class.mi]](class.mi "11.7.2Multiple 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.3Copy/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.3One-definition rule"), [[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#12.sentence-1)
— *end note*]
If an implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-defaulted functions")) constructor would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The 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.5Exception 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.3Initializing 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.3Initializing 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.1General")) of X[.](#15.sentence-1)
For each object nested within ([[intro.object]](intro.object "6.8.2Object 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)