tmp/tmpuvyl2cg0/{from.md → to.md}
RENAMED
|
@@ -1,22 +1,51 @@
|
|
| 1 |
## Temporary objects <a id="class.temporary">[[class.temporary]]</a>
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
[[
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
[[except.throw]].
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
Consider the following code:
|
| 20 |
|
| 21 |
``` cpp
|
| 22 |
class X {
|
|
@@ -43,24 +72,34 @@ void h() {
|
|
| 43 |
Y c = g(Y(3));
|
| 44 |
a = f(a);
|
| 45 |
}
|
| 46 |
```
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
`
|
| 51 |
-
|
| 52 |
-
`
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
When an implementation introduces a temporary object of a class that has
|
| 64 |
a non-trivial constructor ([[class.ctor]], [[class.copy]]), it shall
|
| 65 |
ensure that a constructor is called for the temporary object. Similarly,
|
| 66 |
the destructor shall be called for a temporary with a non-trivial
|
|
@@ -70,42 +109,46 @@ last step in evaluating the full-expression ([[intro.execution]]) that
|
|
| 70 |
even if that evaluation ends in throwing an exception. The value
|
| 71 |
computations and side effects of destroying a temporary object are
|
| 72 |
associated only with the full-expression, not with any specific
|
| 73 |
subexpression.
|
| 74 |
|
| 75 |
-
There are
|
| 76 |
-
point than the end of the full-expression. The first context
|
| 77 |
-
default constructor is called to initialize an element of an
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
-
The
|
| 83 |
temporary to which the reference is bound or the temporary that is the
|
| 84 |
complete object of a subobject to which the reference is bound persists
|
| 85 |
for the lifetime of the reference except:
|
| 86 |
|
| 87 |
-
- A temporary bound to a reference
|
| 88 |
-
*ctor-initializer* ([[class.base.init]]) persists until the
|
| 89 |
-
constructor exits.
|
| 90 |
-
- A temporary bound to a reference parameter in a function call (
|
| 91 |
[[expr.call]]) persists until the completion of the full-expression
|
| 92 |
containing the call.
|
| 93 |
- The lifetime of a temporary bound to the returned value in a function
|
| 94 |
return statement ([[stmt.return]]) is not extended; the temporary is
|
| 95 |
destroyed at the end of the full-expression in the return statement.
|
| 96 |
- A temporary bound to a reference in a *new-initializer* (
|
| 97 |
[[expr.new]]) persists until the completion of the full-expression
|
| 98 |
containing the *new-initializer*.
|
|
|
|
| 99 |
``` cpp
|
| 100 |
struct S { int mi; const std::pair<int,int>& mp; };
|
| 101 |
S a { 1, {2,3} };
|
| 102 |
S* p = new S{ 1, {2,3} }; // Creates dangling reference
|
| 103 |
```
|
| 104 |
|
| 105 |
-
|
| 106 |
-
|
|
|
|
|
|
|
| 107 |
|
| 108 |
The destruction of a temporary whose lifetime is not extended by being
|
| 109 |
bound to a reference is sequenced before the destruction of every
|
| 110 |
temporary which is constructed earlier in the same full-expression. If
|
| 111 |
the lifetime of two or more temporaries to which references are bound
|
|
@@ -119,10 +162,12 @@ storage duration as the temporary and created before the temporary is
|
|
| 119 |
created the temporary shall be destroyed before `obj1` is destroyed; if
|
| 120 |
`obj2` is an object with the same storage duration as the temporary and
|
| 121 |
created after the temporary is created the temporary shall be destroyed
|
| 122 |
after `obj2` is destroyed.
|
| 123 |
|
|
|
|
|
|
|
| 124 |
``` cpp
|
| 125 |
struct S {
|
| 126 |
S();
|
| 127 |
S(int);
|
| 128 |
friend S operator+(const S&, const S&);
|
|
@@ -149,5 +194,7 @@ order in which `T3` is destroyed takes into account the destruction
|
|
| 149 |
order of other objects with static storage duration. That is, because
|
| 150 |
`obj1` is constructed before `T3`, and `T3` is constructed before
|
| 151 |
`obj2`, `obj2` shall be destroyed before `T3`, and `T3` shall be
|
| 152 |
destroyed before `obj1`.
|
| 153 |
|
|
|
|
|
|
|
|
|
| 1 |
## Temporary objects <a id="class.temporary">[[class.temporary]]</a>
|
| 2 |
|
| 3 |
+
Temporary objects are created
|
| 4 |
+
|
| 5 |
+
- when a prvalue is materialized so that it can be used as a glvalue (
|
| 6 |
+
[[conv.rval]]),
|
| 7 |
+
- when needed by the implementation to pass or return an object of
|
| 8 |
+
trivially-copyable type (see below), and
|
| 9 |
+
- when throwing an exception ([[except.throw]]). \[*Note 1*: The
|
| 10 |
+
lifetime of exception objects is described in
|
| 11 |
+
[[except.throw]]. — *end note*]
|
| 12 |
+
|
| 13 |
+
Even when the creation of the temporary object is unevaluated (Clause
|
| 14 |
+
[[expr]]), all the semantic restrictions shall be respected as if the
|
| 15 |
+
temporary object had been created and later destroyed.
|
| 16 |
+
|
| 17 |
+
[*Note 2*: This includes accessibility (Clause [[class.access]]) and
|
| 18 |
+
whether it is deleted, for the constructor selected and for the
|
| 19 |
+
destructor. However, in the special case of the operand of a
|
| 20 |
+
*decltype-specifier* ([[expr.call]]), no temporary is introduced, so
|
| 21 |
+
the foregoing does not apply to such a prvalue. — *end note*]
|
| 22 |
+
|
| 23 |
+
The materialization of a temporary object is generally delayed as long
|
| 24 |
+
as possible in order to avoid creating unnecessary temporary objects.
|
| 25 |
+
|
| 26 |
+
[*Note 3*:
|
| 27 |
+
|
| 28 |
+
Temporary objects are materialized:
|
| 29 |
+
|
| 30 |
+
- when binding a reference to a prvalue ([[dcl.init.ref]],
|
| 31 |
+
[[expr.type.conv]], [[expr.dynamic.cast]], [[expr.static.cast]],
|
| 32 |
+
[[expr.const.cast]], [[expr.cast]]),
|
| 33 |
+
- when performing member access on a class prvalue ([[expr.ref]],
|
| 34 |
+
[[expr.mptr.oper]]),
|
| 35 |
+
- when performing an array-to-pointer conversion or subscripting on an
|
| 36 |
+
array prvalue ([[conv.array]], [[expr.sub]]),
|
| 37 |
+
- when initializing an object of type `std::initializer_list<T>` from a
|
| 38 |
+
*braced-init-list* ([[dcl.init.list]]),
|
| 39 |
+
- for certain unevaluated operands ([[expr.typeid]], [[expr.sizeof]]),
|
| 40 |
+
and
|
| 41 |
+
- when a prvalue appears as a discarded-value expression (Clause
|
| 42 |
+
[[expr]]).
|
| 43 |
+
|
| 44 |
+
— *end note*]
|
| 45 |
+
|
| 46 |
+
[*Example 1*:
|
| 47 |
|
| 48 |
Consider the following code:
|
| 49 |
|
| 50 |
``` cpp
|
| 51 |
class X {
|
|
|
|
| 72 |
Y c = g(Y(3));
|
| 73 |
a = f(a);
|
| 74 |
}
|
| 75 |
```
|
| 76 |
|
| 77 |
+
`X(2)` is constructed in the space used to hold `f()`’s argument and
|
| 78 |
+
`Y(3)` is constructed in the space used to hold `g()`’s argument.
|
| 79 |
+
Likewise, `f()`’s result is constructed directly in `b` and `g()`’s
|
| 80 |
+
result is constructed directly in `c`. On the other hand, the expression
|
| 81 |
+
`a = f(a)` requires a temporary for the result of `f(a)`, which is
|
| 82 |
+
materialized so that the reference parameter of `A::operator=(const A&)`
|
| 83 |
+
can bind to it.
|
| 84 |
+
|
| 85 |
+
— *end example*]
|
| 86 |
+
|
| 87 |
+
When an object of class type `X` is passed to or returned from a
|
| 88 |
+
function, if each copy constructor, move constructor, and destructor of
|
| 89 |
+
`X` is either trivial or deleted, and `X` has at least one non-deleted
|
| 90 |
+
copy or move constructor, implementations are permitted to create a
|
| 91 |
+
temporary object to hold the function parameter or result object. The
|
| 92 |
+
temporary object is constructed from the function argument or return
|
| 93 |
+
value, respectively, and the function’s parameter or return object is
|
| 94 |
+
initialized as if by using the non-deleted trivial constructor to copy
|
| 95 |
+
the temporary (even if that constructor is inaccessible or would not be
|
| 96 |
+
selected by overload resolution to perform a copy or move of the
|
| 97 |
+
object).
|
| 98 |
+
|
| 99 |
+
[*Note 4*: This latitude is granted to allow objects of class type to
|
| 100 |
+
be passed to or returned from functions in registers. — *end note*]
|
| 101 |
|
| 102 |
When an implementation introduces a temporary object of a class that has
|
| 103 |
a non-trivial constructor ([[class.ctor]], [[class.copy]]), it shall
|
| 104 |
ensure that a constructor is called for the temporary object. Similarly,
|
| 105 |
the destructor shall be called for a temporary with a non-trivial
|
|
|
|
| 109 |
even if that evaluation ends in throwing an exception. The value
|
| 110 |
computations and side effects of destroying a temporary object are
|
| 111 |
associated only with the full-expression, not with any specific
|
| 112 |
subexpression.
|
| 113 |
|
| 114 |
+
There are three contexts in which temporaries are destroyed at a
|
| 115 |
+
different point than the end of the full-expression. The first context
|
| 116 |
+
is when a default constructor is called to initialize an element of an
|
| 117 |
+
array with no corresponding initializer ([[dcl.init]]). The second
|
| 118 |
+
context is when a copy constructor is called to copy an element of an
|
| 119 |
+
array while the entire array is copied ([[expr.prim.lambda.capture]],
|
| 120 |
+
[[class.copy]]). In either case, if the constructor has one or more
|
| 121 |
+
default arguments, the destruction of every temporary created in a
|
| 122 |
+
default argument is sequenced before the construction of the next array
|
| 123 |
+
element, if any.
|
| 124 |
|
| 125 |
+
The third context is when a reference is bound to a temporary.[^1] The
|
| 126 |
temporary to which the reference is bound or the temporary that is the
|
| 127 |
complete object of a subobject to which the reference is bound persists
|
| 128 |
for the lifetime of the reference except:
|
| 129 |
|
| 130 |
+
- A temporary object bound to a reference parameter in a function call (
|
|
|
|
|
|
|
|
|
|
| 131 |
[[expr.call]]) persists until the completion of the full-expression
|
| 132 |
containing the call.
|
| 133 |
- The lifetime of a temporary bound to the returned value in a function
|
| 134 |
return statement ([[stmt.return]]) is not extended; the temporary is
|
| 135 |
destroyed at the end of the full-expression in the return statement.
|
| 136 |
- A temporary bound to a reference in a *new-initializer* (
|
| 137 |
[[expr.new]]) persists until the completion of the full-expression
|
| 138 |
containing the *new-initializer*.
|
| 139 |
+
\[*Example 2*:
|
| 140 |
``` cpp
|
| 141 |
struct S { int mi; const std::pair<int,int>& mp; };
|
| 142 |
S a { 1, {2,3} };
|
| 143 |
S* p = new S{ 1, {2,3} }; // Creates dangling reference
|
| 144 |
```
|
| 145 |
|
| 146 |
+
— *end example*]
|
| 147 |
+
\[*Note 5*: This may introduce a dangling reference, and
|
| 148 |
+
implementations are encouraged to issue a warning in such a
|
| 149 |
+
case. — *end note*]
|
| 150 |
|
| 151 |
The destruction of a temporary whose lifetime is not extended by being
|
| 152 |
bound to a reference is sequenced before the destruction of every
|
| 153 |
temporary which is constructed earlier in the same full-expression. If
|
| 154 |
the lifetime of two or more temporaries to which references are bound
|
|
|
|
| 162 |
created the temporary shall be destroyed before `obj1` is destroyed; if
|
| 163 |
`obj2` is an object with the same storage duration as the temporary and
|
| 164 |
created after the temporary is created the temporary shall be destroyed
|
| 165 |
after `obj2` is destroyed.
|
| 166 |
|
| 167 |
+
[*Example 3*:
|
| 168 |
+
|
| 169 |
``` cpp
|
| 170 |
struct S {
|
| 171 |
S();
|
| 172 |
S(int);
|
| 173 |
friend S operator+(const S&, const S&);
|
|
|
|
| 194 |
order of other objects with static storage duration. That is, because
|
| 195 |
`obj1` is constructed before `T3`, and `T3` is constructed before
|
| 196 |
`obj2`, `obj2` shall be destroyed before `T3`, and `T3` shall be
|
| 197 |
destroyed before `obj1`.
|
| 198 |
|
| 199 |
+
— *end example*]
|
| 200 |
+
|