tmp/tmprkcfuupw/{from.md → to.md}
RENAMED
|
@@ -87,59 +87,35 @@ If the class definition does not explicitly declare a copy constructor,
|
|
| 87 |
one is declared *implicitly*. If the class definition declares a move
|
| 88 |
constructor or move assignment operator, the implicitly declared copy
|
| 89 |
constructor is defined as deleted; otherwise, it is defined as
|
| 90 |
defaulted ([[dcl.fct.def]]). The latter case is deprecated if the class
|
| 91 |
has a user-declared copy assignment operator or a user-declared
|
| 92 |
-
destructor.
|
| 93 |
-
|
| 94 |
-
``` cpp
|
| 95 |
-
struct X {
|
| 96 |
-
X(const X&, int);
|
| 97 |
-
};
|
| 98 |
-
```
|
| 99 |
-
|
| 100 |
-
a copy constructor is implicitly-declared. If the user-declared
|
| 101 |
-
constructor is later defined as
|
| 102 |
-
|
| 103 |
-
``` cpp
|
| 104 |
-
X::X(const X& x, int i =0) { /* ... */ }
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
then any use of `X`’s copy constructor is ill-formed because of the
|
| 108 |
-
ambiguity; no diagnostic is required.
|
| 109 |
|
| 110 |
The implicitly-declared copy constructor for a class `X` will have the
|
| 111 |
form
|
| 112 |
|
| 113 |
``` cpp
|
| 114 |
X::X(const X&)
|
| 115 |
```
|
| 116 |
|
| 117 |
-
if
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
`B&`, and
|
| 122 |
-
- for all the non-static data members of `X` that are of a class type
|
| 123 |
-
`M` (or array thereof), each such class type has a copy constructor
|
| 124 |
-
whose first parameter is of type `const` `M&` or `const` `volatile`
|
| 125 |
-
`M&`.[^4]
|
| 126 |
-
|
| 127 |
-
Otherwise, the implicitly-declared copy constructor will have the form
|
| 128 |
|
| 129 |
``` cpp
|
| 130 |
X::X(X&)
|
| 131 |
```
|
| 132 |
|
| 133 |
If the definition of a class `X` does not explicitly declare a move
|
| 134 |
constructor, one will be implicitly declared as defaulted if and only if
|
| 135 |
|
| 136 |
- `X` does not have a user-declared copy constructor,
|
| 137 |
- `X` does not have a user-declared copy assignment operator,
|
| 138 |
-
- `X` does not have a user-declared move assignment operator,
|
| 139 |
-
- `X` does not have a user-declared destructor
|
| 140 |
-
- the move constructor would not be implicitly defined as deleted.
|
| 141 |
|
| 142 |
When the move constructor is not implicitly declared or explicitly
|
| 143 |
supplied, expressions that otherwise would have invoked the move
|
| 144 |
constructor may instead invoke a copy constructor.
|
| 145 |
|
|
@@ -154,56 +130,54 @@ An implicitly-declared copy/move constructor is an `inline` `public`
|
|
| 154 |
member of its class. A defaulted copy/move constructor for a class `X`
|
| 155 |
is defined as deleted ([[dcl.fct.def.delete]]) if `X` has:
|
| 156 |
|
| 157 |
- a variant member with a non-trivial corresponding constructor and `X`
|
| 158 |
is a union-like class,
|
| 159 |
-
- a
|
| 160 |
cannot be copied/moved because overload resolution ([[over.match]]),
|
| 161 |
as applied to `M`’s corresponding constructor, results in an ambiguity
|
| 162 |
or a function that is deleted or inaccessible from the defaulted
|
| 163 |
constructor,
|
| 164 |
-
-
|
| 165 |
-
|
| 166 |
-
corresponding constructor, results in an ambiguity or a function that
|
| 167 |
-
is deleted or inaccessible from the defaulted constructor,
|
| 168 |
-
- any direct or virtual base class or non-static data member of a type
|
| 169 |
-
with a destructor that is deleted or inaccessible from the defaulted
|
| 170 |
-
constructor,
|
| 171 |
- for the copy constructor, a non-static data member of rvalue reference
|
| 172 |
-
type
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
|
|
|
|
|
|
| 176 |
|
| 177 |
A copy/move constructor for class `X` is trivial if it is not
|
| 178 |
-
user-provided
|
|
|
|
| 179 |
|
| 180 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 181 |
base classes ([[class.mi]]), and
|
|
|
|
|
|
|
| 182 |
- the constructor selected to copy/move each direct base class subobject
|
| 183 |
is trivial, and
|
| 184 |
- for each non-static data member of `X` that is of class type (or array
|
| 185 |
thereof), the constructor selected to copy/move that member is
|
| 186 |
trivial;
|
| 187 |
|
| 188 |
otherwise the copy/move constructor is *non-trivial*.
|
| 189 |
|
| 190 |
A copy/move constructor that is defaulted and not defined as deleted is
|
| 191 |
-
*implicitly defined* if it is odr-used ([[basic.def.odr]])
|
| 192 |
-
initialize an object of its class type from a copy of an object of its
|
| 193 |
-
class type or of a class type derived from its class type[^5] or when it
|
| 194 |
is explicitly defaulted after its first declaration. The copy/move
|
| 195 |
constructor is implicitly defined even if the implementation elided its
|
| 196 |
odr-use ([[basic.def.odr]], [[class.temporary]]). If the
|
| 197 |
implicitly-defined constructor would satisfy the requirements of a
|
| 198 |
`constexpr` constructor ([[dcl.constexpr]]), the implicitly-defined
|
| 199 |
constructor is `constexpr`.
|
| 200 |
|
| 201 |
Before the defaulted copy/move constructor for a class is implicitly
|
| 202 |
-
defined, all non-user-provided copy/move constructors for its
|
| 203 |
-
|
| 204 |
-
|
| 205 |
*exception-specification* ([[except.spec]]).
|
| 206 |
|
| 207 |
The implicitly-defined copy/move constructor for a non-union class `X`
|
| 208 |
performs a memberwise copy/move of its bases and members.
|
| 209 |
*brace-or-equal-initializer*s of non-static data members are ignored.
|
|
@@ -229,11 +203,11 @@ The implicitly-defined copy/move constructor for a union `X` copies the
|
|
| 229 |
object representation ([[basic.types]]) of `X`.
|
| 230 |
|
| 231 |
A user-declared *copy* assignment operator `X::operator=` is a
|
| 232 |
non-static non-template member function of class `X` with exactly one
|
| 233 |
parameter of type `X`, `X&`, `const` `X&`, `volatile` `X&` or `const`
|
| 234 |
-
`volatile` `X&`.[^
|
| 235 |
to have only one parameter; see [[over.ass]]. More than one form of
|
| 236 |
copy assignment operator may be declared for a class. If a class `X`
|
| 237 |
only has a copy assignment operator with a parameter of type `X&`, an
|
| 238 |
expression of type const `X` cannot be assigned to an object of type
|
| 239 |
`X`.
|
|
@@ -268,11 +242,11 @@ if
|
|
| 268 |
- each direct base class `B` of `X` has a copy assignment operator whose
|
| 269 |
parameter is of type `const` `B&`, `const` `volatile` `B&` or `B`, and
|
| 270 |
- for all the non-static data members of `X` that are of a class type
|
| 271 |
`M` (or array thereof), each such class type has a copy assignment
|
| 272 |
operator whose parameter is of type `const` `M&`, `const` `volatile`
|
| 273 |
-
`M&` or `M`.[^
|
| 274 |
|
| 275 |
Otherwise, the implicitly-declared copy assignment operator will have
|
| 276 |
the form
|
| 277 |
|
| 278 |
``` cpp
|
|
@@ -290,14 +264,12 @@ If the definition of a class `X` does not explicitly declare a move
|
|
| 290 |
assignment operator, one will be implicitly declared as defaulted if and
|
| 291 |
only if
|
| 292 |
|
| 293 |
- `X` does not have a user-declared copy constructor,
|
| 294 |
- `X` does not have a user-declared move constructor,
|
| 295 |
-
- `X` does not have a user-declared copy assignment operator,
|
| 296 |
-
- `X` does not have a user-declared destructor
|
| 297 |
-
- the move assignment operator would not be implicitly defined as
|
| 298 |
-
deleted.
|
| 299 |
|
| 300 |
The class definition
|
| 301 |
|
| 302 |
``` cpp
|
| 303 |
struct S {
|
|
@@ -337,24 +309,18 @@ deleted if `X` has:
|
|
| 337 |
- a variant member with a non-trivial corresponding assignment operator
|
| 338 |
and `X` is a union-like class, or
|
| 339 |
- a non-static data member of `const` non-class type (or array thereof),
|
| 340 |
or
|
| 341 |
- a non-static data member of reference type, or
|
| 342 |
-
- a
|
| 343 |
-
cannot be copied/moved because overload resolution (
|
| 344 |
-
as applied to `M`’s corresponding assignment
|
| 345 |
-
ambiguity or a function that is deleted or
|
| 346 |
-
defaulted assignment operator
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
function that is deleted or inaccessible from the defaulted assignment
|
| 351 |
-
operator, or
|
| 352 |
-
- for the move assignment operator, a non-static data member or direct
|
| 353 |
-
base class with a type that does not have a move assignment operator
|
| 354 |
-
and is not trivially copyable, or any direct or indirect virtual base
|
| 355 |
-
class.
|
| 356 |
|
| 357 |
Because a copy/move assignment operator is implicitly declared for a
|
| 358 |
class if not declared by the user, a base class copy/move assignment
|
| 359 |
operator is always hidden by the corresponding assignment operator of a
|
| 360 |
derived class ([[over.ass]]). A *using-declaration* (
|
|
@@ -365,27 +331,38 @@ declaration of such an operator and does not suppress the implicit
|
|
| 365 |
declaration of the derived class operator; the operator introduced by
|
| 366 |
the *using-declaration* is hidden by the implicitly-declared operator in
|
| 367 |
the derived class.
|
| 368 |
|
| 369 |
A copy/move assignment operator for class `X` is trivial if it is not
|
| 370 |
-
user-provided
|
|
|
|
| 371 |
|
| 372 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 373 |
base classes ([[class.mi]]), and
|
|
|
|
|
|
|
| 374 |
- the assignment operator selected to copy/move each direct base class
|
| 375 |
subobject is trivial, and
|
| 376 |
- for each non-static data member of `X` that is of class type (or array
|
| 377 |
thereof), the assignment operator selected to copy/move that member is
|
| 378 |
trivial;
|
| 379 |
|
| 380 |
otherwise the copy/move assignment operator is *non-trivial*.
|
| 381 |
|
| 382 |
-
A copy/move assignment operator that is defaulted and
|
| 383 |
-
deleted is *implicitly defined* when it is odr-used (
|
| 384 |
-
(e.g., when it is selected by overload resolution to
|
| 385 |
-
of its class type) or when it is explicitly
|
| 386 |
-
declaration.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 387 |
|
| 388 |
Before the defaulted copy/move assignment operator for a class is
|
| 389 |
implicitly defined, all non-user-provided copy/move assignment operators
|
| 390 |
for its direct base classes and its non-static data members shall have
|
| 391 |
been implicitly defined. An implicitly-declared copy/move assignment
|
|
@@ -436,19 +413,20 @@ member function is not accessible (Clause [[class.access]]).
|
|
| 436 |
Copying/moving one object into another using the copy/move constructor
|
| 437 |
or the copy/move assignment operator does not change the layout or size
|
| 438 |
of either object.
|
| 439 |
|
| 440 |
When certain criteria are met, an implementation is allowed to omit the
|
| 441 |
-
copy/move construction of a class object, even if the
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
copy/move operation as simply two
|
| 445 |
-
|
| 446 |
-
the times when the two objects would
|
| 447 |
-
optimization.[^
|
| 448 |
-
elision*, is permitted in the
|
| 449 |
-
combined to eliminate multiple
|
|
|
|
| 450 |
|
| 451 |
- in a `return` statement in a function with a class return type, when
|
| 452 |
the expression is the name of a non-volatile automatic object (other
|
| 453 |
than a function or catch-clause parameter) with the same
|
| 454 |
cv-unqualified type as the function return type, the copy/move
|
|
@@ -465,14 +443,15 @@ combined to eliminate multiple copies):
|
|
| 465 |
same cv-unqualified type, the copy/move operation can be omitted by
|
| 466 |
constructing the temporary object directly into the target of the
|
| 467 |
omitted copy/move
|
| 468 |
- when the of an exception handler (Clause [[except]]) declares an
|
| 469 |
object of the same type (except for cv-qualification) as the exception
|
| 470 |
-
object ([[except.throw]]), the copy
|
| 471 |
treating the as an alias for the exception object if the meaning of
|
| 472 |
the program will be unchanged except for the execution of constructors
|
| 473 |
-
and destructors for the object declared by the .
|
|
|
|
| 474 |
|
| 475 |
``` cpp
|
| 476 |
class Thing {
|
| 477 |
public:
|
| 478 |
Thing();
|
|
@@ -496,22 +475,25 @@ function `f()` and the copying of that temporary object into object
|
|
| 496 |
viewed as directly initializing the global object `t2`, and that
|
| 497 |
object’s destruction will occur at program exit. Adding a move
|
| 498 |
constructor to `Thing` has the same effect, but it is the move
|
| 499 |
construction from the temporary object to `t2` that is elided.
|
| 500 |
|
| 501 |
-
When the criteria for elision of a copy operation are met
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
|
|
|
|
|
|
|
|
|
| 513 |
|
| 514 |
``` cpp
|
| 515 |
class Thing {
|
| 516 |
public:
|
| 517 |
Thing();
|
|
|
|
| 87 |
one is declared *implicitly*. If the class definition declares a move
|
| 88 |
constructor or move assignment operator, the implicitly declared copy
|
| 89 |
constructor is defined as deleted; otherwise, it is defined as
|
| 90 |
defaulted ([[dcl.fct.def]]). The latter case is deprecated if the class
|
| 91 |
has a user-declared copy assignment operator or a user-declared
|
| 92 |
+
destructor.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
The implicitly-declared copy constructor for a class `X` will have the
|
| 95 |
form
|
| 96 |
|
| 97 |
``` cpp
|
| 98 |
X::X(const X&)
|
| 99 |
```
|
| 100 |
|
| 101 |
+
if each potentially constructed subobject of a class type `M` (or array
|
| 102 |
+
thereof) has a copy constructor whose first parameter is of type `const`
|
| 103 |
+
`M&` or `const` `volatile` `M&`.[^4] Otherwise, the implicitly-declared
|
| 104 |
+
copy constructor will have the form
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
``` cpp
|
| 107 |
X::X(X&)
|
| 108 |
```
|
| 109 |
|
| 110 |
If the definition of a class `X` does not explicitly declare a move
|
| 111 |
constructor, one will be implicitly declared as defaulted if and only if
|
| 112 |
|
| 113 |
- `X` does not have a user-declared copy constructor,
|
| 114 |
- `X` does not have a user-declared copy assignment operator,
|
| 115 |
+
- `X` does not have a user-declared move assignment operator, and
|
| 116 |
+
- `X` does not have a user-declared destructor.
|
|
|
|
| 117 |
|
| 118 |
When the move constructor is not implicitly declared or explicitly
|
| 119 |
supplied, expressions that otherwise would have invoked the move
|
| 120 |
constructor may instead invoke a copy constructor.
|
| 121 |
|
|
|
|
| 130 |
member of its class. A defaulted copy/move constructor for a class `X`
|
| 131 |
is defined as deleted ([[dcl.fct.def.delete]]) if `X` has:
|
| 132 |
|
| 133 |
- a variant member with a non-trivial corresponding constructor and `X`
|
| 134 |
is a union-like class,
|
| 135 |
+
- a potentially constructed subobject type `M` (or array thereof) that
|
| 136 |
cannot be copied/moved because overload resolution ([[over.match]]),
|
| 137 |
as applied to `M`’s corresponding constructor, results in an ambiguity
|
| 138 |
or a function that is deleted or inaccessible from the defaulted
|
| 139 |
constructor,
|
| 140 |
+
- any potentially constructed subobject of a type with a destructor that
|
| 141 |
+
is deleted or inaccessible from the defaulted constructor, or,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
- for the copy constructor, a non-static data member of rvalue reference
|
| 143 |
+
type.
|
| 144 |
+
|
| 145 |
+
A defaulted move constructor that is defined as deleted is ignored by
|
| 146 |
+
overload resolution ([[over.match]], [[over.over]]). A deleted move
|
| 147 |
+
constructor would otherwise interfere with initialization from an rvalue
|
| 148 |
+
which can use the copy constructor instead.
|
| 149 |
|
| 150 |
A copy/move constructor for class `X` is trivial if it is not
|
| 151 |
+
user-provided, its parameter-type-list is equivalent to the
|
| 152 |
+
parameter-type-list of an implicit declaration, and if
|
| 153 |
|
| 154 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 155 |
base classes ([[class.mi]]), and
|
| 156 |
+
- class `X` has no non-static data members of volatile-qualified type,
|
| 157 |
+
and
|
| 158 |
- the constructor selected to copy/move each direct base class subobject
|
| 159 |
is trivial, and
|
| 160 |
- for each non-static data member of `X` that is of class type (or array
|
| 161 |
thereof), the constructor selected to copy/move that member is
|
| 162 |
trivial;
|
| 163 |
|
| 164 |
otherwise the copy/move constructor is *non-trivial*.
|
| 165 |
|
| 166 |
A copy/move constructor that is defaulted and not defined as deleted is
|
| 167 |
+
*implicitly defined* if it is odr-used ([[basic.def.odr]]) or when it
|
|
|
|
|
|
|
| 168 |
is explicitly defaulted after its first declaration. The copy/move
|
| 169 |
constructor is implicitly defined even if the implementation elided its
|
| 170 |
odr-use ([[basic.def.odr]], [[class.temporary]]). If the
|
| 171 |
implicitly-defined constructor would satisfy the requirements of a
|
| 172 |
`constexpr` constructor ([[dcl.constexpr]]), the implicitly-defined
|
| 173 |
constructor is `constexpr`.
|
| 174 |
|
| 175 |
Before the defaulted copy/move constructor for a class is implicitly
|
| 176 |
+
defined, all non-user-provided copy/move constructors for its
|
| 177 |
+
potentially constructed subobjects shall have been implicitly defined.
|
| 178 |
+
An implicitly-declared copy/move constructor has an
|
| 179 |
*exception-specification* ([[except.spec]]).
|
| 180 |
|
| 181 |
The implicitly-defined copy/move constructor for a non-union class `X`
|
| 182 |
performs a memberwise copy/move of its bases and members.
|
| 183 |
*brace-or-equal-initializer*s of non-static data members are ignored.
|
|
|
|
| 203 |
object representation ([[basic.types]]) of `X`.
|
| 204 |
|
| 205 |
A user-declared *copy* assignment operator `X::operator=` is a
|
| 206 |
non-static non-template member function of class `X` with exactly one
|
| 207 |
parameter of type `X`, `X&`, `const` `X&`, `volatile` `X&` or `const`
|
| 208 |
+
`volatile` `X&`.[^5] An overloaded assignment operator must be declared
|
| 209 |
to have only one parameter; see [[over.ass]]. More than one form of
|
| 210 |
copy assignment operator may be declared for a class. If a class `X`
|
| 211 |
only has a copy assignment operator with a parameter of type `X&`, an
|
| 212 |
expression of type const `X` cannot be assigned to an object of type
|
| 213 |
`X`.
|
|
|
|
| 242 |
- each direct base class `B` of `X` has a copy assignment operator whose
|
| 243 |
parameter is of type `const` `B&`, `const` `volatile` `B&` or `B`, and
|
| 244 |
- for all the non-static data members of `X` that are of a class type
|
| 245 |
`M` (or array thereof), each such class type has a copy assignment
|
| 246 |
operator whose parameter is of type `const` `M&`, `const` `volatile`
|
| 247 |
+
`M&` or `M`.[^6]
|
| 248 |
|
| 249 |
Otherwise, the implicitly-declared copy assignment operator will have
|
| 250 |
the form
|
| 251 |
|
| 252 |
``` cpp
|
|
|
|
| 264 |
assignment operator, one will be implicitly declared as defaulted if and
|
| 265 |
only if
|
| 266 |
|
| 267 |
- `X` does not have a user-declared copy constructor,
|
| 268 |
- `X` does not have a user-declared move constructor,
|
| 269 |
+
- `X` does not have a user-declared copy assignment operator, and
|
| 270 |
+
- `X` does not have a user-declared destructor.
|
|
|
|
|
|
|
| 271 |
|
| 272 |
The class definition
|
| 273 |
|
| 274 |
``` cpp
|
| 275 |
struct S {
|
|
|
|
| 309 |
- a variant member with a non-trivial corresponding assignment operator
|
| 310 |
and `X` is a union-like class, or
|
| 311 |
- a non-static data member of `const` non-class type (or array thereof),
|
| 312 |
or
|
| 313 |
- a non-static data member of reference type, or
|
| 314 |
+
- a potentially constructed subobject of class type `M` (or array
|
| 315 |
+
thereof) that cannot be copied/moved because overload resolution (
|
| 316 |
+
[[over.match]]), as applied to `M`’s corresponding assignment
|
| 317 |
+
operator, results in an ambiguity or a function that is deleted or
|
| 318 |
+
inaccessible from the defaulted assignment operator.
|
| 319 |
+
|
| 320 |
+
A defaulted move assignment operator that is defined as deleted is
|
| 321 |
+
ignored by overload resolution ([[over.match]], [[over.over]]).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
|
| 323 |
Because a copy/move assignment operator is implicitly declared for a
|
| 324 |
class if not declared by the user, a base class copy/move assignment
|
| 325 |
operator is always hidden by the corresponding assignment operator of a
|
| 326 |
derived class ([[over.ass]]). A *using-declaration* (
|
|
|
|
| 331 |
declaration of the derived class operator; the operator introduced by
|
| 332 |
the *using-declaration* is hidden by the implicitly-declared operator in
|
| 333 |
the derived class.
|
| 334 |
|
| 335 |
A copy/move assignment operator for class `X` is trivial if it is not
|
| 336 |
+
user-provided, its parameter-type-list is equivalent to the
|
| 337 |
+
parameter-type-list of an implicit declaration, and if
|
| 338 |
|
| 339 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 340 |
base classes ([[class.mi]]), and
|
| 341 |
+
- class `X` has no non-static data members of volatile-qualified type,
|
| 342 |
+
and
|
| 343 |
- the assignment operator selected to copy/move each direct base class
|
| 344 |
subobject is trivial, and
|
| 345 |
- for each non-static data member of `X` that is of class type (or array
|
| 346 |
thereof), the assignment operator selected to copy/move that member is
|
| 347 |
trivial;
|
| 348 |
|
| 349 |
otherwise the copy/move assignment operator is *non-trivial*.
|
| 350 |
|
| 351 |
+
A copy/move assignment operator for a class `X` that is defaulted and
|
| 352 |
+
not defined as deleted is *implicitly defined* when it is odr-used (
|
| 353 |
+
[[basic.def.odr]]) (e.g., when it is selected by overload resolution to
|
| 354 |
+
assign to an object of its class type) or when it is explicitly
|
| 355 |
+
defaulted after its first declaration. The implicitly-defined copy/move
|
| 356 |
+
assignment operator is `constexpr` if
|
| 357 |
+
|
| 358 |
+
- `X` is a literal type, and
|
| 359 |
+
- the assignment operator selected to copy/move each direct base class
|
| 360 |
+
subobject is a `constexpr` function, and
|
| 361 |
+
- for each non-static data member of `X` that is of class type (or array
|
| 362 |
+
thereof), the assignment operator selected to copy/move that member is
|
| 363 |
+
a `constexpr` function.
|
| 364 |
|
| 365 |
Before the defaulted copy/move assignment operator for a class is
|
| 366 |
implicitly defined, all non-user-provided copy/move assignment operators
|
| 367 |
for its direct base classes and its non-static data members shall have
|
| 368 |
been implicitly defined. An implicitly-declared copy/move assignment
|
|
|
|
| 413 |
Copying/moving one object into another using the copy/move constructor
|
| 414 |
or the copy/move assignment operator does not change the layout or size
|
| 415 |
of either object.
|
| 416 |
|
| 417 |
When certain criteria are met, an implementation is allowed to omit the
|
| 418 |
+
copy/move construction of a class object, even if the constructor
|
| 419 |
+
selected for the copy/move operation and/or the destructor for the
|
| 420 |
+
object have side effects. In such cases, the implementation treats the
|
| 421 |
+
source and target of the omitted copy/move operation as simply two
|
| 422 |
+
different ways of referring to the same object, and the destruction of
|
| 423 |
+
that object occurs at the later of the times when the two objects would
|
| 424 |
+
have been destroyed without the optimization.[^7] This elision of
|
| 425 |
+
copy/move operations, called *copy elision*, is permitted in the
|
| 426 |
+
following circumstances (which may be combined to eliminate multiple
|
| 427 |
+
copies):
|
| 428 |
|
| 429 |
- in a `return` statement in a function with a class return type, when
|
| 430 |
the expression is the name of a non-volatile automatic object (other
|
| 431 |
than a function or catch-clause parameter) with the same
|
| 432 |
cv-unqualified type as the function return type, the copy/move
|
|
|
|
| 443 |
same cv-unqualified type, the copy/move operation can be omitted by
|
| 444 |
constructing the temporary object directly into the target of the
|
| 445 |
omitted copy/move
|
| 446 |
- when the of an exception handler (Clause [[except]]) declares an
|
| 447 |
object of the same type (except for cv-qualification) as the exception
|
| 448 |
+
object ([[except.throw]]), the copy operation can be omitted by
|
| 449 |
treating the as an alias for the exception object if the meaning of
|
| 450 |
the program will be unchanged except for the execution of constructors
|
| 451 |
+
and destructors for the object declared by the . There cannot be a
|
| 452 |
+
move from the exception object because it is always an lvalue.
|
| 453 |
|
| 454 |
``` cpp
|
| 455 |
class Thing {
|
| 456 |
public:
|
| 457 |
Thing();
|
|
|
|
| 475 |
viewed as directly initializing the global object `t2`, and that
|
| 476 |
object’s destruction will occur at program exit. Adding a move
|
| 477 |
constructor to `Thing` has the same effect, but it is the move
|
| 478 |
construction from the temporary object to `t2` that is elided.
|
| 479 |
|
| 480 |
+
When the criteria for elision of a copy/move operation are met, but not
|
| 481 |
+
for an , and the object to be copied is designated by an lvalue, or when
|
| 482 |
+
the *expression* in a `return` statement is a (possibly parenthesized)
|
| 483 |
+
*id-expression* that names an object with automatic storage duration
|
| 484 |
+
declared in the body or *parameter-declaration-clause* of the innermost
|
| 485 |
+
enclosing function or *lambda-expression*, overload resolution to select
|
| 486 |
+
the constructor for the copy is first performed as if the object were
|
| 487 |
+
designated by an rvalue. If the first overload resolution fails or was
|
| 488 |
+
not performed, or if the type of the first parameter of the selected
|
| 489 |
+
constructor is not an rvalue reference to the object’s type (possibly
|
| 490 |
+
cv-qualified), overload resolution is performed again, considering the
|
| 491 |
+
object as an lvalue. This two-stage overload resolution must be
|
| 492 |
+
performed regardless of whether copy elision will occur. It determines
|
| 493 |
+
the constructor to be called if elision is not performed, and the
|
| 494 |
+
selected constructor must be accessible even if the call is elided.
|
| 495 |
|
| 496 |
``` cpp
|
| 497 |
class Thing {
|
| 498 |
public:
|
| 499 |
Thing();
|