- tmp/tmpmrrl9h17/{from.md → to.md} +382 -125
tmp/tmpmrrl9h17/{from.md → to.md}
RENAMED
|
@@ -5,15 +5,30 @@ A class object can be copied or moved in two ways: by initialization (
|
|
| 5 |
[[expr.call]]) and for function value return ([[stmt.return]]); and by
|
| 6 |
assignment ([[expr.ass]]). Conceptually, these two operations are
|
| 7 |
implemented by a copy/move constructor ([[class.ctor]]) and copy/move
|
| 8 |
assignment operator ([[over.ass]]).
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
A non-template constructor for class `X` is a copy constructor if its
|
| 11 |
first parameter is of type `X&`, `const X&`, `volatile X&` or
|
| 12 |
`const volatile X&`, and either there are no other parameters or else
|
| 13 |
all other parameters have default arguments ([[dcl.fct.default]]).
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
``` cpp
|
| 17 |
struct X {
|
| 18 |
X(int);
|
| 19 |
X(const X&, int = 1);
|
|
@@ -21,14 +36,19 @@ struct X {
|
|
| 21 |
X a(1); // calls X(int);
|
| 22 |
X b(a, 0); // calls X(const X&, int);
|
| 23 |
X c = b; // calls X(const X&, int);
|
| 24 |
```
|
| 25 |
|
|
|
|
|
|
|
| 26 |
A non-template constructor for class `X` is a move constructor if its
|
| 27 |
first parameter is of type `X&&`, `const X&&`, `volatile X&&`, or
|
| 28 |
`const volatile X&&`, and either there are no other parameters or else
|
| 29 |
all other parameters have default arguments ([[dcl.fct.default]]).
|
|
|
|
|
|
|
|
|
|
| 30 |
`Y::Y(Y&&)` is a move constructor.
|
| 31 |
|
| 32 |
``` cpp
|
| 33 |
struct Y {
|
| 34 |
Y(const Y&);
|
|
@@ -37,40 +57,60 @@ struct Y {
|
|
| 37 |
extern Y f(int);
|
| 38 |
Y d(f(1)); // calls Y(Y&&)
|
| 39 |
Y e = d; // calls Y(const Y&)
|
| 40 |
```
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
All forms of copy/move constructor may be declared for a class.
|
| 43 |
|
|
|
|
|
|
|
| 44 |
``` cpp
|
| 45 |
struct X {
|
| 46 |
X(const X&);
|
| 47 |
X(X&); // OK
|
| 48 |
X(X&&);
|
| 49 |
X(const X&&); // OK, but possibly not sensible
|
| 50 |
};
|
| 51 |
```
|
| 52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
If a class `X` only has a copy constructor with a parameter of type
|
| 54 |
`X&`, an initializer of type `const` `X` or `volatile` `X` cannot
|
| 55 |
initialize an object of type (possibly cv-qualified) `X`.
|
| 56 |
|
|
|
|
|
|
|
| 57 |
``` cpp
|
| 58 |
struct X {
|
| 59 |
X(); // default constructor
|
| 60 |
-
X(X&); // copy constructor with a
|
| 61 |
};
|
| 62 |
const X cx;
|
| 63 |
X x = cx; // error: X::X(X&) cannot copy cx into x
|
| 64 |
```
|
| 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
A declaration of a constructor for a class `X` is ill-formed if its
|
| 67 |
first parameter is of type (optionally cv-qualified) `X` and either
|
| 68 |
there are no other parameters or else all other parameters have default
|
| 69 |
arguments. A member function template is never instantiated to produce
|
| 70 |
such a constructor signature.
|
| 71 |
|
|
|
|
|
|
|
| 72 |
``` cpp
|
| 73 |
struct S {
|
| 74 |
template<typename T> S(T);
|
| 75 |
S();
|
| 76 |
};
|
|
@@ -81,17 +121,19 @@ void h() {
|
|
| 81 |
S a(g); // does not instantiate the member template to produce S::S<S>(S);
|
| 82 |
// uses the implicitly declared copy constructor
|
| 83 |
}
|
| 84 |
```
|
| 85 |
|
|
|
|
|
|
|
| 86 |
If the class definition does not explicitly declare a copy constructor,
|
| 87 |
-
one is declared *implicitly*. If the class definition
|
| 88 |
-
constructor or move assignment operator, the implicitly
|
| 89 |
-
constructor is defined as deleted; otherwise, it is
|
| 90 |
-
defaulted ([[dcl.fct.def]]). The latter case is deprecated
|
| 91 |
-
has a user-declared copy assignment operator or a
|
| 92 |
-
destructor.
|
| 93 |
|
| 94 |
The implicitly-declared copy constructor for a class `X` will have the
|
| 95 |
form
|
| 96 |
|
| 97 |
``` cpp
|
|
@@ -106,20 +148,21 @@ copy constructor will have the form
|
|
| 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
|
|
|
|
| 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
|
| 119 |
-
supplied, expressions that otherwise would have invoked the
|
| 120 |
-
constructor may instead invoke a copy constructor.
|
| 121 |
|
| 122 |
The implicitly-declared move constructor for class `X` will have the
|
| 123 |
form
|
| 124 |
|
| 125 |
``` cpp
|
|
@@ -132,64 +175,69 @@ 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
|
| 138 |
-
or a function that is deleted or inaccessible from the
|
| 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]]).
|
| 147 |
-
|
| 148 |
-
|
|
|
|
|
|
|
| 149 |
|
| 150 |
A copy/move constructor for class `X` is trivial if it is not
|
| 151 |
-
user-provided
|
| 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.
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 179 |
-
*
|
|
|
|
| 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 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
|
|
|
|
|
|
| 191 |
|
| 192 |
- if the member is an array, each element is direct-initialized with the
|
| 193 |
corresponding subobject of `x`;
|
| 194 |
- if a member `m` has rvalue reference type `T&&`, it is
|
| 195 |
direct-initialized with `static_cast<T&&>(x.m)`;
|
|
@@ -200,19 +248,30 @@ Virtual base class subobjects shall be initialized only once by the
|
|
| 200 |
implicitly-defined copy/move constructor (see [[class.base.init]]).
|
| 201 |
|
| 202 |
The implicitly-defined copy/move constructor for a union `X` copies the
|
| 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]
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
only
|
| 212 |
-
|
| 213 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
|
| 215 |
``` cpp
|
| 216 |
struct X {
|
| 217 |
X();
|
| 218 |
X& operator=(X&);
|
|
@@ -222,10 +281,14 @@ X x;
|
|
| 222 |
void f() {
|
| 223 |
x = cx; // error: X::operator=(X&) cannot assign cx into x
|
| 224 |
}
|
| 225 |
```
|
| 226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
If the class definition does not explicitly declare a copy assignment
|
| 228 |
operator, one is declared *implicitly*. If the class definition declares
|
| 229 |
a move constructor or move assignment operator, the implicitly declared
|
| 230 |
copy assignment operator is defined as deleted; otherwise, it is defined
|
| 231 |
as defaulted ([[dcl.fct.def]]). The latter case is deprecated if the
|
|
@@ -253,24 +316,29 @@ the form
|
|
| 253 |
X& X::operator=(X&)
|
| 254 |
```
|
| 255 |
|
| 256 |
A user-declared move assignment operator `X::operator=` is a non-static
|
| 257 |
non-template member function of class `X` with exactly one parameter of
|
| 258 |
-
type `X&&`, `const X&&`, `volatile X&&`, or `const volatile X&&`.
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
If the definition of a class `X` does not explicitly declare a move
|
| 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 {
|
| 276 |
int a;
|
|
@@ -288,10 +356,12 @@ struct S {
|
|
| 288 |
S& operator=(const S&) = default;
|
| 289 |
S& operator=(S&&) = default;
|
| 290 |
};
|
| 291 |
```
|
| 292 |
|
|
|
|
|
|
|
| 293 |
The implicitly-declared move assignment operator for a class `X` will
|
| 294 |
have the form
|
| 295 |
|
| 296 |
``` cpp
|
| 297 |
X& X::operator=(X&&);
|
|
@@ -309,15 +379,16 @@ deleted if `X` has:
|
|
| 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
|
| 315 |
-
|
| 316 |
-
[[over.match]]), as applied to `M`’s
|
| 317 |
-
operator, results in an ambiguity or a
|
| 318 |
-
inaccessible from the defaulted assignment
|
|
|
|
| 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
|
|
@@ -331,17 +402,14 @@ declaration of such an operator and does not suppress the implicit
|
|
| 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
|
| 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;
|
|
@@ -355,20 +423,22 @@ 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
|
| 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
|
| 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.
|
| 369 |
-
|
|
|
|
|
|
|
| 370 |
|
| 371 |
The implicitly-defined copy/move assignment operator for a non-union
|
| 372 |
class `X` performs memberwise copy/move assignment of its subobjects.
|
| 373 |
The direct base classes of `X` are assigned first, in the order of their
|
| 374 |
declaration in the *base-specifier-list*, and then the immediate
|
|
@@ -387,71 +457,79 @@ type:
|
|
| 387 |
appropriate to the element type;
|
| 388 |
- if the subobject is of scalar type, the built-in assignment operator
|
| 389 |
is used.
|
| 390 |
|
| 391 |
It is unspecified whether subobjects representing virtual base classes
|
| 392 |
-
are assigned more than once by the implicitly-defined copy
|
| 393 |
-
operator.
|
|
|
|
|
|
|
| 394 |
|
| 395 |
``` cpp
|
| 396 |
struct V { };
|
| 397 |
struct A : virtual V { };
|
| 398 |
struct B : virtual V { };
|
| 399 |
struct C : B, A { };
|
| 400 |
```
|
| 401 |
|
| 402 |
It is unspecified whether the virtual base class subobject `V` is
|
| 403 |
-
assigned twice by the implicitly-defined copy assignment operator
|
| 404 |
-
`C`.
|
| 405 |
-
|
|
|
|
| 406 |
|
| 407 |
The implicitly-defined copy assignment operator for a union `X` copies
|
| 408 |
the object representation ([[basic.types]]) of `X`.
|
| 409 |
|
| 410 |
-
|
| 411 |
-
assignment operator for an object is implicitly odr-used and the special
|
| 412 |
-
member function is not accessible (Clause [[class.access]]).
|
| 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
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
|
|
|
|
|
|
| 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
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
|
| 454 |
``` cpp
|
| 455 |
class Thing {
|
| 456 |
public:
|
| 457 |
Thing();
|
|
@@ -463,37 +541,67 @@ Thing f() {
|
|
| 463 |
Thing t;
|
| 464 |
return t;
|
| 465 |
}
|
| 466 |
|
| 467 |
Thing t2 = f();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 468 |
```
|
| 469 |
|
| 470 |
-
Here the criteria for elision can
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
`t2`
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
construction from the temporary object to `t2` that is elided.
|
| 479 |
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
the
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
the
|
| 494 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 495 |
|
| 496 |
``` cpp
|
| 497 |
class Thing {
|
| 498 |
public:
|
| 499 |
Thing();
|
|
@@ -508,8 +616,157 @@ Thing f(bool b) {
|
|
| 508 |
if (b)
|
| 509 |
throw t; // OK: Thing(Thing&&) used (or elided) to throw t
|
| 510 |
return t; // OK: Thing(Thing&&) used (or elided) to return t
|
| 511 |
}
|
| 512 |
|
| 513 |
-
Thing t2 = f(false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 514 |
```
|
| 515 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
[[expr.call]]) and for function value return ([[stmt.return]]); and by
|
| 6 |
assignment ([[expr.ass]]). Conceptually, these two operations are
|
| 7 |
implemented by a copy/move constructor ([[class.ctor]]) and copy/move
|
| 8 |
assignment operator ([[over.ass]]).
|
| 9 |
|
| 10 |
+
A program is ill-formed if the copy/move constructor or the copy/move
|
| 11 |
+
assignment operator for an object is implicitly odr-used and the special
|
| 12 |
+
member function is not accessible (Clause [[class.access]]).
|
| 13 |
+
|
| 14 |
+
[*Note 1*: Copying/moving one object into another using the copy/move
|
| 15 |
+
constructor or the copy/move assignment operator does not change the
|
| 16 |
+
layout or size of either object. — *end note*]
|
| 17 |
+
|
| 18 |
+
### Copy/move constructors <a id="class.copy.ctor">[[class.copy.ctor]]</a>
|
| 19 |
+
|
| 20 |
A non-template constructor for class `X` is a copy constructor if its
|
| 21 |
first parameter is of type `X&`, `const X&`, `volatile X&` or
|
| 22 |
`const volatile X&`, and either there are no other parameters or else
|
| 23 |
all other parameters have default arguments ([[dcl.fct.default]]).
|
| 24 |
+
|
| 25 |
+
[*Example 1*:
|
| 26 |
+
|
| 27 |
+
`X::X(const X&)`
|
| 28 |
+
|
| 29 |
+
and `X::X(X&,int=1)` are copy constructors.
|
| 30 |
|
| 31 |
``` cpp
|
| 32 |
struct X {
|
| 33 |
X(int);
|
| 34 |
X(const X&, int = 1);
|
|
|
|
| 36 |
X a(1); // calls X(int);
|
| 37 |
X b(a, 0); // calls X(const X&, int);
|
| 38 |
X c = b; // calls X(const X&, int);
|
| 39 |
```
|
| 40 |
|
| 41 |
+
— *end example*]
|
| 42 |
+
|
| 43 |
A non-template constructor for class `X` is a move constructor if its
|
| 44 |
first parameter is of type `X&&`, `const X&&`, `volatile X&&`, or
|
| 45 |
`const volatile X&&`, and either there are no other parameters or else
|
| 46 |
all other parameters have default arguments ([[dcl.fct.default]]).
|
| 47 |
+
|
| 48 |
+
[*Example 2*:
|
| 49 |
+
|
| 50 |
`Y::Y(Y&&)` is a move constructor.
|
| 51 |
|
| 52 |
``` cpp
|
| 53 |
struct Y {
|
| 54 |
Y(const Y&);
|
|
|
|
| 57 |
extern Y f(int);
|
| 58 |
Y d(f(1)); // calls Y(Y&&)
|
| 59 |
Y e = d; // calls Y(const Y&)
|
| 60 |
```
|
| 61 |
|
| 62 |
+
— *end example*]
|
| 63 |
+
|
| 64 |
+
[*Note 1*:
|
| 65 |
+
|
| 66 |
All forms of copy/move constructor may be declared for a class.
|
| 67 |
|
| 68 |
+
[*Example 3*:
|
| 69 |
+
|
| 70 |
``` cpp
|
| 71 |
struct X {
|
| 72 |
X(const X&);
|
| 73 |
X(X&); // OK
|
| 74 |
X(X&&);
|
| 75 |
X(const X&&); // OK, but possibly not sensible
|
| 76 |
};
|
| 77 |
```
|
| 78 |
|
| 79 |
+
— *end example*]
|
| 80 |
+
|
| 81 |
+
— *end note*]
|
| 82 |
+
|
| 83 |
+
[*Note 2*:
|
| 84 |
+
|
| 85 |
If a class `X` only has a copy constructor with a parameter of type
|
| 86 |
`X&`, an initializer of type `const` `X` or `volatile` `X` cannot
|
| 87 |
initialize an object of type (possibly cv-qualified) `X`.
|
| 88 |
|
| 89 |
+
[*Example 4*:
|
| 90 |
+
|
| 91 |
``` cpp
|
| 92 |
struct X {
|
| 93 |
X(); // default constructor
|
| 94 |
+
X(X&); // copy constructor with a non-const parameter
|
| 95 |
};
|
| 96 |
const X cx;
|
| 97 |
X x = cx; // error: X::X(X&) cannot copy cx into x
|
| 98 |
```
|
| 99 |
|
| 100 |
+
— *end example*]
|
| 101 |
+
|
| 102 |
+
— *end note*]
|
| 103 |
+
|
| 104 |
A declaration of a constructor for a class `X` is ill-formed if its
|
| 105 |
first parameter is of type (optionally cv-qualified) `X` and either
|
| 106 |
there are no other parameters or else all other parameters have default
|
| 107 |
arguments. A member function template is never instantiated to produce
|
| 108 |
such a constructor signature.
|
| 109 |
|
| 110 |
+
[*Example 5*:
|
| 111 |
+
|
| 112 |
``` cpp
|
| 113 |
struct S {
|
| 114 |
template<typename T> S(T);
|
| 115 |
S();
|
| 116 |
};
|
|
|
|
| 121 |
S a(g); // does not instantiate the member template to produce S::S<S>(S);
|
| 122 |
// uses the implicitly declared copy constructor
|
| 123 |
}
|
| 124 |
```
|
| 125 |
|
| 126 |
+
— *end example*]
|
| 127 |
+
|
| 128 |
If the class definition does not explicitly declare a copy constructor,
|
| 129 |
+
a non-explicit one is declared *implicitly*. If the class definition
|
| 130 |
+
declares a move constructor or move assignment operator, the implicitly
|
| 131 |
+
declared copy constructor is defined as deleted; otherwise, it is
|
| 132 |
+
defined as defaulted ([[dcl.fct.def]]). The latter case is deprecated
|
| 133 |
+
if the class has a user-declared copy assignment operator or a
|
| 134 |
+
user-declared destructor.
|
| 135 |
|
| 136 |
The implicitly-declared copy constructor for a class `X` will have the
|
| 137 |
form
|
| 138 |
|
| 139 |
``` cpp
|
|
|
|
| 148 |
``` cpp
|
| 149 |
X::X(X&)
|
| 150 |
```
|
| 151 |
|
| 152 |
If the definition of a class `X` does not explicitly declare a move
|
| 153 |
+
constructor, a non-explicit one will be implicitly declared as defaulted
|
| 154 |
+
if and only if
|
| 155 |
|
| 156 |
- `X` does not have a user-declared copy constructor,
|
| 157 |
- `X` does not have a user-declared copy assignment operator,
|
| 158 |
- `X` does not have a user-declared move assignment operator, and
|
| 159 |
- `X` does not have a user-declared destructor.
|
| 160 |
|
| 161 |
+
[*Note 3*: When the move constructor is not implicitly declared or
|
| 162 |
+
explicitly supplied, expressions that otherwise would have invoked the
|
| 163 |
+
move constructor may instead invoke a copy constructor. — *end note*]
|
| 164 |
|
| 165 |
The implicitly-declared move constructor for class `X` will have the
|
| 166 |
form
|
| 167 |
|
| 168 |
``` cpp
|
|
|
|
| 175 |
|
| 176 |
- a variant member with a non-trivial corresponding constructor and `X`
|
| 177 |
is a union-like class,
|
| 178 |
- a potentially constructed subobject type `M` (or array thereof) that
|
| 179 |
cannot be copied/moved because overload resolution ([[over.match]]),
|
| 180 |
+
as applied to find `M`’s corresponding constructor, results in an
|
| 181 |
+
ambiguity or a function that is deleted or inaccessible from the
|
| 182 |
+
defaulted constructor,
|
| 183 |
- any potentially constructed subobject of a type with a destructor that
|
| 184 |
is deleted or inaccessible from the defaulted constructor, or,
|
| 185 |
- for the copy constructor, a non-static data member of rvalue reference
|
| 186 |
type.
|
| 187 |
|
| 188 |
A defaulted move constructor that is defined as deleted is ignored by
|
| 189 |
+
overload resolution ([[over.match]], [[over.over]]).
|
| 190 |
+
|
| 191 |
+
[*Note 4*: A deleted move constructor would otherwise interfere with
|
| 192 |
+
initialization from an rvalue which can use the copy constructor
|
| 193 |
+
instead. — *end note*]
|
| 194 |
|
| 195 |
A copy/move constructor for class `X` is trivial if it is not
|
| 196 |
+
user-provided and if:
|
|
|
|
| 197 |
|
| 198 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 199 |
base classes ([[class.mi]]), and
|
|
|
|
|
|
|
| 200 |
- the constructor selected to copy/move each direct base class subobject
|
| 201 |
is trivial, and
|
| 202 |
- for each non-static data member of `X` that is of class type (or array
|
| 203 |
thereof), the constructor selected to copy/move that member is
|
| 204 |
trivial;
|
| 205 |
|
| 206 |
otherwise the copy/move constructor is *non-trivial*.
|
| 207 |
|
| 208 |
A copy/move constructor that is defaulted and not defined as deleted is
|
| 209 |
*implicitly defined* if it is odr-used ([[basic.def.odr]]) or when it
|
| 210 |
+
is explicitly defaulted after its first declaration.
|
| 211 |
+
|
| 212 |
+
[*Note 5*: The copy/move constructor is implicitly defined even if the
|
| 213 |
+
implementation elided its odr-use ([[basic.def.odr]],
|
| 214 |
+
[[class.temporary]]). — *end note*]
|
| 215 |
+
|
| 216 |
+
If the implicitly-defined constructor would satisfy the requirements of
|
| 217 |
+
a constexpr constructor ([[dcl.constexpr]]), the implicitly-defined
|
| 218 |
constructor is `constexpr`.
|
| 219 |
|
| 220 |
Before the defaulted copy/move constructor for a class is implicitly
|
| 221 |
defined, all non-user-provided copy/move constructors for its
|
| 222 |
potentially constructed subobjects shall have been implicitly defined.
|
| 223 |
+
|
| 224 |
+
[*Note 6*: An implicitly-declared copy/move constructor has an implied
|
| 225 |
+
exception specification ([[except.spec]]). — *end note*]
|
| 226 |
|
| 227 |
The implicitly-defined copy/move constructor for a non-union class `X`
|
| 228 |
performs a memberwise copy/move of its bases and members.
|
| 229 |
+
|
| 230 |
+
[*Note 7*: Default member initializers of non-static data members are
|
| 231 |
+
ignored. See also the example in [[class.base.init]]. — *end note*]
|
| 232 |
+
|
| 233 |
+
The order of initialization is the same as the order of initialization
|
| 234 |
+
of bases and members in a user-defined constructor (see
|
| 235 |
+
[[class.base.init]]). Let `x` be either the parameter of the constructor
|
| 236 |
+
or, for the move constructor, an xvalue referring to the parameter. Each
|
| 237 |
+
base or non-static data member is copied/moved in the manner appropriate
|
| 238 |
+
to its type:
|
| 239 |
|
| 240 |
- if the member is an array, each element is direct-initialized with the
|
| 241 |
corresponding subobject of `x`;
|
| 242 |
- if a member `m` has rvalue reference type `T&&`, it is
|
| 243 |
direct-initialized with `static_cast<T&&>(x.m)`;
|
|
|
|
| 248 |
implicitly-defined copy/move constructor (see [[class.base.init]]).
|
| 249 |
|
| 250 |
The implicitly-defined copy/move constructor for a union `X` copies the
|
| 251 |
object representation ([[basic.types]]) of `X`.
|
| 252 |
|
| 253 |
+
### Copy/move assignment operator <a id="class.copy.assign">[[class.copy.assign]]</a>
|
| 254 |
+
|
| 255 |
A user-declared *copy* assignment operator `X::operator=` is a
|
| 256 |
non-static non-template member function of class `X` with exactly one
|
| 257 |
parameter of type `X`, `X&`, `const` `X&`, `volatile` `X&` or `const`
|
| 258 |
+
`volatile` `X&`.[^5]
|
| 259 |
+
|
| 260 |
+
[*Note 1*: An overloaded assignment operator must be declared to have
|
| 261 |
+
only one parameter; see [[over.ass]]. — *end note*]
|
| 262 |
+
|
| 263 |
+
[*Note 2*: More than one form of copy assignment operator may be
|
| 264 |
+
declared for a class. — *end note*]
|
| 265 |
+
|
| 266 |
+
[*Note 3*:
|
| 267 |
+
|
| 268 |
+
If a class `X` only has a copy assignment operator with a parameter of
|
| 269 |
+
type `X&`, an expression of type const `X` cannot be assigned to an
|
| 270 |
+
object of type `X`.
|
| 271 |
+
|
| 272 |
+
[*Example 1*:
|
| 273 |
|
| 274 |
``` cpp
|
| 275 |
struct X {
|
| 276 |
X();
|
| 277 |
X& operator=(X&);
|
|
|
|
| 281 |
void f() {
|
| 282 |
x = cx; // error: X::operator=(X&) cannot assign cx into x
|
| 283 |
}
|
| 284 |
```
|
| 285 |
|
| 286 |
+
— *end example*]
|
| 287 |
+
|
| 288 |
+
— *end note*]
|
| 289 |
+
|
| 290 |
If the class definition does not explicitly declare a copy assignment
|
| 291 |
operator, one is declared *implicitly*. If the class definition declares
|
| 292 |
a move constructor or move assignment operator, the implicitly declared
|
| 293 |
copy assignment operator is defined as deleted; otherwise, it is defined
|
| 294 |
as defaulted ([[dcl.fct.def]]). The latter case is deprecated if the
|
|
|
|
| 316 |
X& X::operator=(X&)
|
| 317 |
```
|
| 318 |
|
| 319 |
A user-declared move assignment operator `X::operator=` is a non-static
|
| 320 |
non-template member function of class `X` with exactly one parameter of
|
| 321 |
+
type `X&&`, `const X&&`, `volatile X&&`, or `const volatile X&&`.
|
| 322 |
+
|
| 323 |
+
[*Note 4*: An overloaded assignment operator must be declared to have
|
| 324 |
+
only one parameter; see [[over.ass]]. — *end note*]
|
| 325 |
+
|
| 326 |
+
[*Note 5*: More than one form of move assignment operator may be
|
| 327 |
+
declared for a class. — *end note*]
|
| 328 |
|
| 329 |
If the definition of a class `X` does not explicitly declare a move
|
| 330 |
assignment operator, one will be implicitly declared as defaulted if and
|
| 331 |
only if
|
| 332 |
|
| 333 |
- `X` does not have a user-declared copy constructor,
|
| 334 |
- `X` does not have a user-declared move constructor,
|
| 335 |
- `X` does not have a user-declared copy assignment operator, and
|
| 336 |
- `X` does not have a user-declared destructor.
|
| 337 |
|
| 338 |
+
[*Example 2*:
|
| 339 |
+
|
| 340 |
The class definition
|
| 341 |
|
| 342 |
``` cpp
|
| 343 |
struct S {
|
| 344 |
int a;
|
|
|
|
| 356 |
S& operator=(const S&) = default;
|
| 357 |
S& operator=(S&&) = default;
|
| 358 |
};
|
| 359 |
```
|
| 360 |
|
| 361 |
+
— *end example*]
|
| 362 |
+
|
| 363 |
The implicitly-declared move assignment operator for a class `X` will
|
| 364 |
have the form
|
| 365 |
|
| 366 |
``` cpp
|
| 367 |
X& X::operator=(X&&);
|
|
|
|
| 379 |
- a variant member with a non-trivial corresponding assignment operator
|
| 380 |
and `X` is a union-like class, or
|
| 381 |
- a non-static data member of `const` non-class type (or array thereof),
|
| 382 |
or
|
| 383 |
- a non-static data member of reference type, or
|
| 384 |
+
- a direct non-static data member of class type `M` (or array thereof)
|
| 385 |
+
or a direct base class `M` that cannot be copied/moved because
|
| 386 |
+
overload resolution ([[over.match]]), as applied to find `M`’s
|
| 387 |
+
corresponding assignment operator, results in an ambiguity or a
|
| 388 |
+
function that is deleted or inaccessible from the defaulted assignment
|
| 389 |
+
operator.
|
| 390 |
|
| 391 |
A defaulted move assignment operator that is defined as deleted is
|
| 392 |
ignored by overload resolution ([[over.match]], [[over.over]]).
|
| 393 |
|
| 394 |
Because a copy/move assignment operator is implicitly declared for a
|
|
|
|
| 402 |
declaration of the derived class operator; the operator introduced by
|
| 403 |
the *using-declaration* is hidden by the implicitly-declared operator in
|
| 404 |
the derived class.
|
| 405 |
|
| 406 |
A copy/move assignment operator for class `X` is trivial if it is not
|
| 407 |
+
user-provided and if:
|
|
|
|
| 408 |
|
| 409 |
- class `X` has no virtual functions ([[class.virtual]]) and no virtual
|
| 410 |
base classes ([[class.mi]]), and
|
|
|
|
|
|
|
| 411 |
- the assignment operator selected to copy/move each direct base class
|
| 412 |
subobject is trivial, and
|
| 413 |
- for each non-static data member of `X` that is of class type (or array
|
| 414 |
thereof), the assignment operator selected to copy/move that member is
|
| 415 |
trivial;
|
|
|
|
| 423 |
defaulted after its first declaration. The implicitly-defined copy/move
|
| 424 |
assignment operator is `constexpr` if
|
| 425 |
|
| 426 |
- `X` is a literal type, and
|
| 427 |
- the assignment operator selected to copy/move each direct base class
|
| 428 |
+
subobject is a constexpr function, and
|
| 429 |
- for each non-static data member of `X` that is of class type (or array
|
| 430 |
thereof), the assignment operator selected to copy/move that member is
|
| 431 |
+
a constexpr function.
|
| 432 |
|
| 433 |
Before the defaulted copy/move assignment operator for a class is
|
| 434 |
implicitly defined, all non-user-provided copy/move assignment operators
|
| 435 |
for its direct base classes and its non-static data members shall have
|
| 436 |
+
been implicitly defined.
|
| 437 |
+
|
| 438 |
+
[*Note 6*: An implicitly-declared copy/move assignment operator has an
|
| 439 |
+
implied exception specification ([[except.spec]]). — *end note*]
|
| 440 |
|
| 441 |
The implicitly-defined copy/move assignment operator for a non-union
|
| 442 |
class `X` performs memberwise copy/move assignment of its subobjects.
|
| 443 |
The direct base classes of `X` are assigned first, in the order of their
|
| 444 |
declaration in the *base-specifier-list*, and then the immediate
|
|
|
|
| 457 |
appropriate to the element type;
|
| 458 |
- if the subobject is of scalar type, the built-in assignment operator
|
| 459 |
is used.
|
| 460 |
|
| 461 |
It is unspecified whether subobjects representing virtual base classes
|
| 462 |
+
are assigned more than once by the implicitly-defined copy/move
|
| 463 |
+
assignment operator.
|
| 464 |
+
|
| 465 |
+
[*Example 3*:
|
| 466 |
|
| 467 |
``` cpp
|
| 468 |
struct V { };
|
| 469 |
struct A : virtual V { };
|
| 470 |
struct B : virtual V { };
|
| 471 |
struct C : B, A { };
|
| 472 |
```
|
| 473 |
|
| 474 |
It is unspecified whether the virtual base class subobject `V` is
|
| 475 |
+
assigned twice by the implicitly-defined copy/move assignment operator
|
| 476 |
+
for `C`.
|
| 477 |
+
|
| 478 |
+
— *end example*]
|
| 479 |
|
| 480 |
The implicitly-defined copy assignment operator for a union `X` copies
|
| 481 |
the object representation ([[basic.types]]) of `X`.
|
| 482 |
|
| 483 |
+
### Copy/move elision <a id="class.copy.elision">[[class.copy.elision]]</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
|
| 485 |
When certain criteria are met, an implementation is allowed to omit the
|
| 486 |
copy/move construction of a class object, even if the constructor
|
| 487 |
selected for the copy/move operation and/or the destructor for the
|
| 488 |
object have side effects. In such cases, the implementation treats the
|
| 489 |
source and target of the omitted copy/move operation as simply two
|
| 490 |
+
different ways of referring to the same object. If the first parameter
|
| 491 |
+
of the selected constructor is an rvalue reference to the object’s type,
|
| 492 |
+
the destruction of that object occurs when the target would have been
|
| 493 |
+
destroyed; otherwise, the destruction occurs at the later of the times
|
| 494 |
+
when the two objects would have been destroyed without the
|
| 495 |
+
optimization.[^7] This elision of copy/move operations, called *copy
|
| 496 |
+
elision*, is permitted in the following circumstances (which may be
|
| 497 |
+
combined to eliminate multiple copies):
|
| 498 |
|
| 499 |
- in a `return` statement in a function with a class return type, when
|
| 500 |
+
the *expression* is the name of a non-volatile automatic object (other
|
| 501 |
+
than a function parameter or a variable introduced by the
|
| 502 |
+
*exception-declaration* of a *handler* ([[except.handle]])) with the
|
| 503 |
+
same type (ignoring cv-qualification) as the function return type, the
|
| 504 |
+
copy/move operation can be omitted by constructing the automatic
|
| 505 |
+
object directly into the function call’s return object
|
| 506 |
+
- in a *throw-expression* ([[expr.throw]]), when the operand is the
|
| 507 |
+
name of a non-volatile automatic object (other than a function or
|
| 508 |
+
catch-clause parameter) whose scope does not extend beyond the end of
|
| 509 |
+
the innermost enclosing *try-block* (if there is one), the copy/move
|
| 510 |
+
operation from the operand to the exception object ([[except.throw]])
|
| 511 |
+
can be omitted by constructing the automatic object directly into the
|
| 512 |
+
exception object
|
| 513 |
+
- when the *exception-declaration* of an exception handler (Clause
|
| 514 |
+
[[except]]) declares an object of the same type (except for
|
| 515 |
+
cv-qualification) as the exception object ([[except.throw]]), the
|
| 516 |
+
copy operation can be omitted by treating the *exception-declaration*
|
| 517 |
+
as an alias for the exception object if the meaning of the program
|
| 518 |
+
will be unchanged except for the execution of constructors and
|
| 519 |
+
destructors for the object declared by the *exception-declaration*.
|
| 520 |
+
\[*Note 1*: There cannot be a move from the exception object because
|
| 521 |
+
it is always an lvalue. — *end note*]
|
| 522 |
+
|
| 523 |
+
Copy elision is required where an expression is evaluated in a context
|
| 524 |
+
requiring a constant expression ([[expr.const]]) and in constant
|
| 525 |
+
initialization ([[basic.start.static]]).
|
| 526 |
+
|
| 527 |
+
[*Note 2*: Copy elision might not be performed if the same expression
|
| 528 |
+
is evaluated in another context. — *end note*]
|
| 529 |
+
|
| 530 |
+
[*Example 1*:
|
| 531 |
|
| 532 |
``` cpp
|
| 533 |
class Thing {
|
| 534 |
public:
|
| 535 |
Thing();
|
|
|
|
| 541 |
Thing t;
|
| 542 |
return t;
|
| 543 |
}
|
| 544 |
|
| 545 |
Thing t2 = f();
|
| 546 |
+
|
| 547 |
+
struct A {
|
| 548 |
+
void *p;
|
| 549 |
+
constexpr A(): p(this) {}
|
| 550 |
+
};
|
| 551 |
+
|
| 552 |
+
constexpr A g() {
|
| 553 |
+
A a;
|
| 554 |
+
return a;
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
constexpr A a; // well-formed, a.p points to a
|
| 558 |
+
constexpr A b = g(); // well-formed, b.p points to b
|
| 559 |
+
|
| 560 |
+
void g() {
|
| 561 |
+
A c = g(); // well-formed, c.p may point to c or to an ephemeral temporary
|
| 562 |
+
}
|
| 563 |
```
|
| 564 |
|
| 565 |
+
Here the criteria for elision can eliminate the copying of the local
|
| 566 |
+
automatic object `t` into the result object for the function call `f()`,
|
| 567 |
+
which is the global object `t2`. Effectively, the construction of the
|
| 568 |
+
local object `t` can be viewed as directly initializing the global
|
| 569 |
+
object `t2`, and that object’s destruction will occur at program exit.
|
| 570 |
+
Adding a move constructor to `Thing` has the same effect, but it is the
|
| 571 |
+
move construction from the local automatic object to `t2` that is
|
| 572 |
+
elided.
|
|
|
|
| 573 |
|
| 574 |
+
— *end example*]
|
| 575 |
+
|
| 576 |
+
In the following copy-initialization contexts, a move operation might be
|
| 577 |
+
used instead of a copy operation:
|
| 578 |
+
|
| 579 |
+
- If the *expression* in a `return` statement ([[stmt.return]]) is a
|
| 580 |
+
(possibly parenthesized) *id-expression* that names an object with
|
| 581 |
+
automatic storage duration declared in the body or
|
| 582 |
+
*parameter-declaration-clause* of the innermost enclosing function or
|
| 583 |
+
*lambda-expression*, or
|
| 584 |
+
- if the operand of a *throw-expression* ([[expr.throw]]) is the name
|
| 585 |
+
of a non-volatile automatic object (other than a function or
|
| 586 |
+
catch-clause parameter) whose scope does not extend beyond the end of
|
| 587 |
+
the innermost enclosing *try-block* (if there is one),
|
| 588 |
+
|
| 589 |
+
overload resolution to select the constructor for the copy is first
|
| 590 |
+
performed as if the object were designated by an rvalue. If the first
|
| 591 |
+
overload resolution fails or was not performed, or if the type of the
|
| 592 |
+
first parameter of the selected constructor is not an rvalue reference
|
| 593 |
+
to the object’s type (possibly cv-qualified), overload resolution is
|
| 594 |
+
performed again, considering the object as an lvalue.
|
| 595 |
+
|
| 596 |
+
[*Note 3*: This two-stage overload resolution must be performed
|
| 597 |
+
regardless of whether copy elision will occur. It determines the
|
| 598 |
+
constructor to be called if elision is not performed, and the selected
|
| 599 |
+
constructor must be accessible even if the call is
|
| 600 |
+
elided. — *end note*]
|
| 601 |
+
|
| 602 |
+
[*Example 2*:
|
| 603 |
|
| 604 |
``` cpp
|
| 605 |
class Thing {
|
| 606 |
public:
|
| 607 |
Thing();
|
|
|
|
| 616 |
if (b)
|
| 617 |
throw t; // OK: Thing(Thing&&) used (or elided) to throw t
|
| 618 |
return t; // OK: Thing(Thing&&) used (or elided) to return t
|
| 619 |
}
|
| 620 |
|
| 621 |
+
Thing t2 = f(false); // OK: no extra copy/move performed, t2 constructed by call to f
|
| 622 |
+
|
| 623 |
+
struct Weird {
|
| 624 |
+
Weird();
|
| 625 |
+
Weird(Weird&);
|
| 626 |
+
};
|
| 627 |
+
|
| 628 |
+
Weird g() {
|
| 629 |
+
Weird w;
|
| 630 |
+
return w; // OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
|
| 631 |
+
}
|
| 632 |
```
|
| 633 |
|
| 634 |
+
— *end example*]
|
| 635 |
+
|
| 636 |
+
<!-- Link reference definitions -->
|
| 637 |
+
[basic.def.odr]: basic.md#basic.def.odr
|
| 638 |
+
[basic.life]: basic.md#basic.life
|
| 639 |
+
[basic.lookup]: basic.md#basic.lookup
|
| 640 |
+
[basic.lval]: basic.md#basic.lval
|
| 641 |
+
[basic.start.dynamic]: basic.md#basic.start.dynamic
|
| 642 |
+
[basic.start.static]: basic.md#basic.start.static
|
| 643 |
+
[basic.start.term]: basic.md#basic.start.term
|
| 644 |
+
[basic.stc.auto]: basic.md#basic.stc.auto
|
| 645 |
+
[basic.stc.dynamic]: basic.md#basic.stc.dynamic
|
| 646 |
+
[basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
|
| 647 |
+
[basic.stc.static]: basic.md#basic.stc.static
|
| 648 |
+
[basic.stc.thread]: basic.md#basic.stc.thread
|
| 649 |
+
[basic.types]: basic.md#basic.types
|
| 650 |
+
[class]: class.md#class
|
| 651 |
+
[class.abstract]: class.md#class.abstract
|
| 652 |
+
[class.access]: class.md#class.access
|
| 653 |
+
[class.base.init]: #class.base.init
|
| 654 |
+
[class.cdtor]: #class.cdtor
|
| 655 |
+
[class.conv]: #class.conv
|
| 656 |
+
[class.conv.ctor]: #class.conv.ctor
|
| 657 |
+
[class.conv.fct]: #class.conv.fct
|
| 658 |
+
[class.copy]: #class.copy
|
| 659 |
+
[class.copy.assign]: #class.copy.assign
|
| 660 |
+
[class.copy.ctor]: #class.copy.ctor
|
| 661 |
+
[class.copy.elision]: #class.copy.elision
|
| 662 |
+
[class.ctor]: #class.ctor
|
| 663 |
+
[class.dtor]: #class.dtor
|
| 664 |
+
[class.expl.init]: #class.expl.init
|
| 665 |
+
[class.free]: #class.free
|
| 666 |
+
[class.friend]: class.md#class.friend
|
| 667 |
+
[class.inhctor.init]: #class.inhctor.init
|
| 668 |
+
[class.init]: #class.init
|
| 669 |
+
[class.mem]: class.md#class.mem
|
| 670 |
+
[class.member.lookup]: class.md#class.member.lookup
|
| 671 |
+
[class.mfct]: class.md#class.mfct
|
| 672 |
+
[class.mi]: class.md#class.mi
|
| 673 |
+
[class.qual]: basic.md#class.qual
|
| 674 |
+
[class.temporary]: #class.temporary
|
| 675 |
+
[class.union]: class.md#class.union
|
| 676 |
+
[class.union.anon]: class.md#class.union.anon
|
| 677 |
+
[class.virtual]: class.md#class.virtual
|
| 678 |
+
[conv]: conv.md#conv
|
| 679 |
+
[conv.array]: conv.md#conv.array
|
| 680 |
+
[conv.rval]: conv.md#conv.rval
|
| 681 |
+
[dcl.array]: dcl.md#dcl.array
|
| 682 |
+
[dcl.constexpr]: dcl.md#dcl.constexpr
|
| 683 |
+
[dcl.fct]: dcl.md#dcl.fct
|
| 684 |
+
[dcl.fct.def]: dcl.md#dcl.fct.def
|
| 685 |
+
[dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
|
| 686 |
+
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 687 |
+
[dcl.fct.spec]: dcl.md#dcl.fct.spec
|
| 688 |
+
[dcl.init]: dcl.md#dcl.init
|
| 689 |
+
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 690 |
+
[dcl.init.list]: dcl.md#dcl.init.list
|
| 691 |
+
[dcl.init.ref]: dcl.md#dcl.init.ref
|
| 692 |
+
[dcl.spec.auto]: dcl.md#dcl.spec.auto
|
| 693 |
+
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 694 |
+
[diff.special]: compatibility.md#diff.special
|
| 695 |
+
[except]: except.md#except
|
| 696 |
+
[except.ctor]: except.md#except.ctor
|
| 697 |
+
[except.handle]: except.md#except.handle
|
| 698 |
+
[except.spec]: except.md#except.spec
|
| 699 |
+
[except.throw]: except.md#except.throw
|
| 700 |
+
[expr]: expr.md#expr
|
| 701 |
+
[expr.ass]: expr.md#expr.ass
|
| 702 |
+
[expr.call]: expr.md#expr.call
|
| 703 |
+
[expr.cast]: expr.md#expr.cast
|
| 704 |
+
[expr.const]: expr.md#expr.const
|
| 705 |
+
[expr.const.cast]: expr.md#expr.const.cast
|
| 706 |
+
[expr.delete]: expr.md#expr.delete
|
| 707 |
+
[expr.dynamic.cast]: expr.md#expr.dynamic.cast
|
| 708 |
+
[expr.mptr.oper]: expr.md#expr.mptr.oper
|
| 709 |
+
[expr.new]: expr.md#expr.new
|
| 710 |
+
[expr.prim]: expr.md#expr.prim
|
| 711 |
+
[expr.prim.lambda.capture]: expr.md#expr.prim.lambda.capture
|
| 712 |
+
[expr.pseudo]: expr.md#expr.pseudo
|
| 713 |
+
[expr.ref]: expr.md#expr.ref
|
| 714 |
+
[expr.sizeof]: expr.md#expr.sizeof
|
| 715 |
+
[expr.static.cast]: expr.md#expr.static.cast
|
| 716 |
+
[expr.sub]: expr.md#expr.sub
|
| 717 |
+
[expr.throw]: expr.md#expr.throw
|
| 718 |
+
[expr.type.conv]: expr.md#expr.type.conv
|
| 719 |
+
[expr.typeid]: expr.md#expr.typeid
|
| 720 |
+
[expr.unary.op]: expr.md#expr.unary.op
|
| 721 |
+
[intro.execution]: intro.md#intro.execution
|
| 722 |
+
[intro.object]: intro.md#intro.object
|
| 723 |
+
[namespace.udecl]: dcl.md#namespace.udecl
|
| 724 |
+
[over.ass]: over.md#over.ass
|
| 725 |
+
[over.best.ics]: over.md#over.best.ics
|
| 726 |
+
[over.ics.ref]: over.md#over.ics.ref
|
| 727 |
+
[over.match]: over.md#over.match
|
| 728 |
+
[over.match.best]: over.md#over.match.best
|
| 729 |
+
[over.match.copy]: over.md#over.match.copy
|
| 730 |
+
[over.over]: over.md#over.over
|
| 731 |
+
[special]: #special
|
| 732 |
+
[stmt.dcl]: stmt.md#stmt.dcl
|
| 733 |
+
[stmt.return]: stmt.md#stmt.return
|
| 734 |
+
[temp.dep.type]: temp.md#temp.dep.type
|
| 735 |
+
[temp.variadic]: temp.md#temp.variadic
|
| 736 |
+
|
| 737 |
+
[^1]: The same rules apply to initialization of an `initializer_list`
|
| 738 |
+
object ([[dcl.init.list]]) with its underlying temporary array.
|
| 739 |
+
|
| 740 |
+
[^2]: These conversions are considered as standard conversions for the
|
| 741 |
+
purposes of overload resolution ([[over.best.ics]],
|
| 742 |
+
[[over.ics.ref]]) and therefore initialization ([[dcl.init]]) and
|
| 743 |
+
explicit casts ([[expr.static.cast]]). A conversion to `void` does
|
| 744 |
+
not invoke any conversion function ([[expr.static.cast]]). Even
|
| 745 |
+
though never directly called to perform a conversion, such
|
| 746 |
+
conversion functions can be declared and can potentially be reached
|
| 747 |
+
through a call to a virtual conversion function in a base class.
|
| 748 |
+
|
| 749 |
+
[^3]: A similar provision is not needed for the array version of
|
| 750 |
+
`operator` `delete` because [[expr.delete]] requires that in this
|
| 751 |
+
situation, the static type of the object to be deleted be the same
|
| 752 |
+
as its dynamic type.
|
| 753 |
+
|
| 754 |
+
[^4]: This implies that the reference parameter of the
|
| 755 |
+
implicitly-declared copy constructor cannot bind to a `volatile`
|
| 756 |
+
lvalue; see [[diff.special]].
|
| 757 |
+
|
| 758 |
+
[^5]: Because a template assignment operator or an assignment operator
|
| 759 |
+
taking an rvalue reference parameter is never a copy assignment
|
| 760 |
+
operator, the presence of such an assignment operator does not
|
| 761 |
+
suppress the implicit declaration of a copy assignment operator.
|
| 762 |
+
Such assignment operators participate in overload resolution with
|
| 763 |
+
other assignment operators, including copy assignment operators,
|
| 764 |
+
and, if selected, will be used to assign an object.
|
| 765 |
+
|
| 766 |
+
[^6]: This implies that the reference parameter of the
|
| 767 |
+
implicitly-declared copy assignment operator cannot bind to a
|
| 768 |
+
`volatile` lvalue; see [[diff.special]].
|
| 769 |
+
|
| 770 |
+
[^7]: Because only one object is destroyed instead of two, and one
|
| 771 |
+
copy/move constructor is not executed, there is still one object
|
| 772 |
+
destroyed for each one constructed.
|