From Jason Turner

[class.copy.assign]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2nzk_yt4/{from.md → to.md} +230 -0
tmp/tmp2nzk_yt4/{from.md → to.md} RENAMED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Copy/move assignment operator <a id="class.copy.assign">[[class.copy.assign]]</a>
2
+
3
+ A user-declared *copy* assignment operator `X::operator=` is a
4
+ non-static non-template member function of class `X` with exactly one
5
+ parameter of type `X`, `X&`, `const` `X&`, `volatile` `X&` or `const`
6
+ `volatile` `X&`.[^5]
7
+
8
+ [*Note 1*: An overloaded assignment operator must be declared to have
9
+ only one parameter; see  [[over.ass]]. — *end note*]
10
+
11
+ [*Note 2*: More than one form of copy assignment operator may be
12
+ declared for a class. — *end note*]
13
+
14
+ [*Note 3*:
15
+
16
+ If a class `X` only has a copy assignment operator with a parameter of
17
+ type `X&`, an expression of type const `X` cannot be assigned to an
18
+ object of type `X`.
19
+
20
+ [*Example 1*:
21
+
22
+ ``` cpp
23
+ struct X {
24
+ X();
25
+ X& operator=(X&);
26
+ };
27
+ const X cx;
28
+ X x;
29
+ void f() {
30
+ x = cx; // error: X::operator=(X&) cannot assign cx into x
31
+ }
32
+ ```
33
+
34
+ — *end example*]
35
+
36
+ — *end note*]
37
+
38
+ If the class definition does not explicitly declare a copy assignment
39
+ operator, one is declared *implicitly*. If the class definition declares
40
+ a move constructor or move assignment operator, the implicitly declared
41
+ copy assignment operator is defined as deleted; otherwise, it is defined
42
+ as defaulted ([[dcl.fct.def]]). The latter case is deprecated if the
43
+ class has a user-declared copy constructor or a user-declared
44
+ destructor. The implicitly-declared copy assignment operator for a class
45
+ `X` will have the form
46
+
47
+ ``` cpp
48
+ X& X::operator=(const X&)
49
+ ```
50
+
51
+ if
52
+
53
+ - each direct base class `B` of `X` has a copy assignment operator whose
54
+ parameter is of type `const` `B&`, `const` `volatile` `B&` or `B`, and
55
+ - for all the non-static data members of `X` that are of a class type
56
+ `M` (or array thereof), each such class type has a copy assignment
57
+ operator whose parameter is of type `const` `M&`, `const` `volatile`
58
+ `M&` or `M`.[^6]
59
+
60
+ Otherwise, the implicitly-declared copy assignment operator will have
61
+ the form
62
+
63
+ ``` cpp
64
+ X& X::operator=(X&)
65
+ ```
66
+
67
+ A user-declared move assignment operator `X::operator=` is a non-static
68
+ non-template member function of class `X` with exactly one parameter of
69
+ type `X&&`, `const X&&`, `volatile X&&`, or `const volatile X&&`.
70
+
71
+ [*Note 4*: An overloaded assignment operator must be declared to have
72
+ only one parameter; see  [[over.ass]]. — *end note*]
73
+
74
+ [*Note 5*: More than one form of move assignment operator may be
75
+ declared for a class. — *end note*]
76
+
77
+ If the definition of a class `X` does not explicitly declare a move
78
+ assignment operator, one will be implicitly declared as defaulted if and
79
+ only if
80
+
81
+ - `X` does not have a user-declared copy constructor,
82
+ - `X` does not have a user-declared move constructor,
83
+ - `X` does not have a user-declared copy assignment operator, and
84
+ - `X` does not have a user-declared destructor.
85
+
86
+ [*Example 2*:
87
+
88
+ The class definition
89
+
90
+ ``` cpp
91
+ struct S {
92
+ int a;
93
+ S& operator=(const S&) = default;
94
+ };
95
+ ```
96
+
97
+ will not have a default move assignment operator implicitly declared
98
+ because the copy assignment operator has been user-declared. The move
99
+ assignment operator may be explicitly defaulted.
100
+
101
+ ``` cpp
102
+ struct S {
103
+ int a;
104
+ S& operator=(const S&) = default;
105
+ S& operator=(S&&) = default;
106
+ };
107
+ ```
108
+
109
+ — *end example*]
110
+
111
+ The implicitly-declared move assignment operator for a class `X` will
112
+ have the form
113
+
114
+ ``` cpp
115
+ X& X::operator=(X&&);
116
+ ```
117
+
118
+ The implicitly-declared copy/move assignment operator for class `X` has
119
+ the return type `X&`; it returns the object for which the assignment
120
+ operator is invoked, that is, the object assigned to. An
121
+ implicitly-declared copy/move assignment operator is an `inline`
122
+ `public` member of its class.
123
+
124
+ A defaulted copy/move assignment operator for class `X` is defined as
125
+ deleted if `X` has:
126
+
127
+ - a variant member with a non-trivial corresponding assignment operator
128
+ and `X` is a union-like class, or
129
+ - a non-static data member of `const` non-class type (or array thereof),
130
+ or
131
+ - a non-static data member of reference type, or
132
+ - a direct non-static data member of class type `M` (or array thereof)
133
+ or a direct base class `M` that cannot be copied/moved because
134
+ overload resolution ([[over.match]]), as applied to find `M`’s
135
+ corresponding assignment operator, results in an ambiguity or a
136
+ function that is deleted or inaccessible from the defaulted assignment
137
+ operator.
138
+
139
+ A defaulted move assignment operator that is defined as deleted is
140
+ ignored by overload resolution ([[over.match]], [[over.over]]).
141
+
142
+ Because a copy/move assignment operator is implicitly declared for a
143
+ class if not declared by the user, a base class copy/move assignment
144
+ operator is always hidden by the corresponding assignment operator of a
145
+ derived class ([[over.ass]]). A *using-declaration* (
146
+ [[namespace.udecl]]) that brings in from a base class an assignment
147
+ operator with a parameter type that could be that of a copy/move
148
+ assignment operator for the derived class is not considered an explicit
149
+ declaration of such an operator and does not suppress the implicit
150
+ declaration of the derived class operator; the operator introduced by
151
+ the *using-declaration* is hidden by the implicitly-declared operator in
152
+ the derived class.
153
+
154
+ A copy/move assignment operator for class `X` is trivial if it is not
155
+ user-provided and if:
156
+
157
+ - class `X` has no virtual functions ([[class.virtual]]) and no virtual
158
+ base classes ([[class.mi]]), and
159
+ - the assignment operator selected to copy/move each direct base class
160
+ subobject is trivial, and
161
+ - for each non-static data member of `X` that is of class type (or array
162
+ thereof), the assignment operator selected to copy/move that member is
163
+ trivial;
164
+
165
+ otherwise the copy/move assignment operator is *non-trivial*.
166
+
167
+ A copy/move assignment operator for a class `X` that is defaulted and
168
+ not defined as deleted is *implicitly defined* when it is odr-used (
169
+ [[basic.def.odr]]) (e.g., when it is selected by overload resolution to
170
+ assign to an object of its class type) or when it is explicitly
171
+ defaulted after its first declaration. The implicitly-defined copy/move
172
+ assignment operator is `constexpr` if
173
+
174
+ - `X` is a literal type, and
175
+ - the assignment operator selected to copy/move each direct base class
176
+ subobject is a constexpr function, and
177
+ - for each non-static data member of `X` that is of class type (or array
178
+ thereof), the assignment operator selected to copy/move that member is
179
+ a constexpr function.
180
+
181
+ Before the defaulted copy/move assignment operator for a class is
182
+ implicitly defined, all non-user-provided copy/move assignment operators
183
+ for its direct base classes and its non-static data members shall have
184
+ been implicitly defined.
185
+
186
+ [*Note 6*: An implicitly-declared copy/move assignment operator has an
187
+ implied exception specification ([[except.spec]]). — *end note*]
188
+
189
+ The implicitly-defined copy/move assignment operator for a non-union
190
+ class `X` performs memberwise copy/move assignment of its subobjects.
191
+ The direct base classes of `X` are assigned first, in the order of their
192
+ declaration in the *base-specifier-list*, and then the immediate
193
+ non-static data members of `X` are assigned, in the order in which they
194
+ were declared in the class definition. Let `x` be either the parameter
195
+ of the function or, for the move operator, an xvalue referring to the
196
+ parameter. Each subobject is assigned in the manner appropriate to its
197
+ type:
198
+
199
+ - if the subobject is of class type, as if by a call to `operator=` with
200
+ the subobject as the object expression and the corresponding subobject
201
+ of `x` as a single function argument (as if by explicit qualification;
202
+ that is, ignoring any possible virtual overriding functions in more
203
+ derived classes);
204
+ - if the subobject is an array, each element is assigned, in the manner
205
+ appropriate to the element type;
206
+ - if the subobject is of scalar type, the built-in assignment operator
207
+ is used.
208
+
209
+ It is unspecified whether subobjects representing virtual base classes
210
+ are assigned more than once by the implicitly-defined copy/move
211
+ assignment operator.
212
+
213
+ [*Example 3*:
214
+
215
+ ``` cpp
216
+ struct V { };
217
+ struct A : virtual V { };
218
+ struct B : virtual V { };
219
+ struct C : B, A { };
220
+ ```
221
+
222
+ It is unspecified whether the virtual base class subobject `V` is
223
+ assigned twice by the implicitly-defined copy/move assignment operator
224
+ for `C`.
225
+
226
+ — *end example*]
227
+
228
+ The implicitly-defined copy assignment operator for a union `X` copies
229
+ the object representation ([[basic.types]]) of `X`.
230
+