tmp/tmpigujr9vp/{from.md → to.md}
RENAMED
|
@@ -2,44 +2,42 @@
|
|
| 2 |
|
| 3 |
Temporary objects are created
|
| 4 |
|
| 5 |
- when a prvalue is converted to an xvalue [[conv.rval]],
|
| 6 |
- when needed by the implementation to pass or return an object of
|
| 7 |
-
trivially
|
| 8 |
- when throwing an exception [[except.throw]]. \[*Note 1*: The lifetime
|
| 9 |
of exception objects is described in [[except.throw]]. — *end note*]
|
| 10 |
|
| 11 |
Even when the creation of the temporary object is unevaluated
|
| 12 |
-
[[expr.
|
| 13 |
the temporary object had been created and later destroyed.
|
| 14 |
|
| 15 |
[*Note 2*: This includes accessibility [[class.access]] and whether it
|
| 16 |
is deleted, for the constructor selected and for the destructor.
|
| 17 |
However, in the special case of the operand of a *decltype-specifier*
|
| 18 |
-
[[
|
| 19 |
-
apply to such a prvalue. — *end note*]
|
| 20 |
|
| 21 |
The materialization of a temporary object is generally delayed as long
|
| 22 |
as possible in order to avoid creating unnecessary temporary objects.
|
| 23 |
|
| 24 |
[*Note 3*:
|
| 25 |
|
| 26 |
Temporary objects are materialized:
|
| 27 |
|
| 28 |
-
- when binding a reference to a prvalue
|
| 29 |
-
[[expr.type.conv]], [[expr.dynamic.cast]], [[expr.static.cast]],
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
[[expr.mptr.oper]]),
|
| 33 |
- when performing an array-to-pointer conversion or subscripting on an
|
| 34 |
-
array prvalue
|
| 35 |
- when initializing an object of type `std::initializer_list<T>` from a
|
| 36 |
*braced-init-list* [[dcl.init.list]],
|
| 37 |
-
- for certain unevaluated operands
|
| 38 |
-
and
|
| 39 |
- when a prvalue that has type other than cv `void` appears as a
|
| 40 |
-
discarded-value expression [[expr.
|
| 41 |
|
| 42 |
— *end note*]
|
| 43 |
|
| 44 |
[*Example 1*:
|
| 45 |
|
|
@@ -96,38 +94,38 @@ object).
|
|
| 96 |
|
| 97 |
[*Note 4*: This latitude is granted to allow objects of class type to
|
| 98 |
be passed to or returned from functions in registers. — *end note*]
|
| 99 |
|
| 100 |
When an implementation introduces a temporary object of a class that has
|
| 101 |
-
a non-trivial constructor
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
|
| 112 |
-
There are
|
| 113 |
different point than the end of the full-expression. The first context
|
| 114 |
is when a default constructor is called to initialize an element of an
|
| 115 |
array with no corresponding initializer [[dcl.init]]. The second context
|
| 116 |
is when a copy constructor is called to copy an element of an array
|
| 117 |
-
while the entire array is copied
|
| 118 |
-
[[class.copy.ctor]]
|
| 119 |
-
default arguments, the destruction of
|
| 120 |
-
default argument is sequenced before the
|
| 121 |
-
element, if any.
|
| 122 |
|
| 123 |
-
The third context is when a reference
|
| 124 |
-
|
| 125 |
-
temporary object
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
following:
|
| 129 |
|
| 130 |
- a temporary materialization conversion [[conv.rval]],
|
| 131 |
- `(` *expression* `)`, where *expression* is one of these expressions,
|
| 132 |
- subscripting [[expr.sub]] of an array operand, where that operand is
|
| 133 |
one of these expressions,
|
|
@@ -166,11 +164,11 @@ int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
|
|
| 166 |
|
| 167 |
— *end example*]
|
| 168 |
|
| 169 |
[*Note 5*:
|
| 170 |
|
| 171 |
-
An explicit type conversion
|
| 172 |
interpreted as a sequence of elementary casts, covered above.
|
| 173 |
|
| 174 |
[*Example 3*:
|
| 175 |
|
| 176 |
``` cpp
|
|
@@ -213,35 +211,43 @@ The exceptions to this lifetime rule are:
|
|
| 213 |
`return` statement [[stmt.return]] is not extended; the temporary is
|
| 214 |
destroyed at the end of the full-expression in the `return` statement.
|
| 215 |
- A temporary bound to a reference in a *new-initializer* [[expr.new]]
|
| 216 |
persists until the completion of the full-expression containing the
|
| 217 |
*new-initializer*.
|
| 218 |
-
\[*Note 7*: This
|
| 219 |
\[*Example 5*:
|
| 220 |
``` cpp
|
| 221 |
struct S { int mi; const std::pair<int,int>& mp; };
|
| 222 |
S a { 1, {2,3} };
|
| 223 |
S* p = new S{ 1, {2,3} }; // creates dangling reference
|
| 224 |
```
|
| 225 |
|
| 226 |
— *end example*]
|
| 227 |
|
| 228 |
-
The
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
[*Example 6*:
|
| 245 |
|
| 246 |
``` cpp
|
| 247 |
struct S {
|
|
|
|
| 2 |
|
| 3 |
Temporary objects are created
|
| 4 |
|
| 5 |
- when a prvalue is converted to an xvalue [[conv.rval]],
|
| 6 |
- when needed by the implementation to pass or return an object of
|
| 7 |
+
trivially copyable type (see below), and
|
| 8 |
- when throwing an exception [[except.throw]]. \[*Note 1*: The lifetime
|
| 9 |
of exception objects is described in [[except.throw]]. — *end note*]
|
| 10 |
|
| 11 |
Even when the creation of the temporary object is unevaluated
|
| 12 |
+
[[expr.context]], all the semantic restrictions shall be respected as if
|
| 13 |
the temporary object had been created and later destroyed.
|
| 14 |
|
| 15 |
[*Note 2*: This includes accessibility [[class.access]] and whether it
|
| 16 |
is deleted, for the constructor selected and for the destructor.
|
| 17 |
However, in the special case of the operand of a *decltype-specifier*
|
| 18 |
+
[[dcl.type.decltype]], no temporary is introduced, so the foregoing does
|
| 19 |
+
not apply to such a prvalue. — *end note*]
|
| 20 |
|
| 21 |
The materialization of a temporary object is generally delayed as long
|
| 22 |
as possible in order to avoid creating unnecessary temporary objects.
|
| 23 |
|
| 24 |
[*Note 3*:
|
| 25 |
|
| 26 |
Temporary objects are materialized:
|
| 27 |
|
| 28 |
+
- when binding a reference to a prvalue
|
| 29 |
+
[[dcl.init.ref]], [[expr.type.conv]], [[expr.dynamic.cast]], [[expr.static.cast]], [[expr.const.cast]], [[expr.cast]],
|
| 30 |
+
- when performing member access on a class prvalue
|
| 31 |
+
[[expr.ref]], [[expr.mptr.oper]],
|
|
|
|
| 32 |
- when performing an array-to-pointer conversion or subscripting on an
|
| 33 |
+
array prvalue [[conv.array]], [[expr.sub]],
|
| 34 |
- when initializing an object of type `std::initializer_list<T>` from a
|
| 35 |
*braced-init-list* [[dcl.init.list]],
|
| 36 |
+
- for certain unevaluated operands [[expr.typeid]], [[expr.sizeof]], and
|
|
|
|
| 37 |
- when a prvalue that has type other than cv `void` appears as a
|
| 38 |
+
discarded-value expression [[expr.context]].
|
| 39 |
|
| 40 |
— *end note*]
|
| 41 |
|
| 42 |
[*Example 1*:
|
| 43 |
|
|
|
|
| 94 |
|
| 95 |
[*Note 4*: This latitude is granted to allow objects of class type to
|
| 96 |
be passed to or returned from functions in registers. — *end note*]
|
| 97 |
|
| 98 |
When an implementation introduces a temporary object of a class that has
|
| 99 |
+
a non-trivial constructor [[class.default.ctor]], [[class.copy.ctor]],
|
| 100 |
+
it shall ensure that a constructor is called for the temporary object.
|
| 101 |
+
Similarly, the destructor shall be called for a temporary with a
|
| 102 |
+
non-trivial destructor [[class.dtor]]. Temporary objects are destroyed
|
| 103 |
+
as the last step in evaluating the full-expression [[intro.execution]]
|
| 104 |
+
that (lexically) contains the point where they were created. This is
|
| 105 |
+
true even if that evaluation ends in throwing an exception. The value
|
| 106 |
+
computations and side effects of destroying a temporary object are
|
| 107 |
+
associated only with the full-expression, not with any specific
|
| 108 |
+
subexpression.
|
| 109 |
|
| 110 |
+
There are four contexts in which temporaries are destroyed at a
|
| 111 |
different point than the end of the full-expression. The first context
|
| 112 |
is when a default constructor is called to initialize an element of an
|
| 113 |
array with no corresponding initializer [[dcl.init]]. The second context
|
| 114 |
is when a copy constructor is called to copy an element of an array
|
| 115 |
+
while the entire array is copied
|
| 116 |
+
[[expr.prim.lambda.capture]], [[class.copy.ctor]]. In either case, if
|
| 117 |
+
the constructor has one or more default arguments, the destruction of
|
| 118 |
+
every temporary created in a default argument is sequenced before the
|
| 119 |
+
construction of the next array element, if any.
|
| 120 |
|
| 121 |
+
The third context is when a reference binds to a temporary object.[^13]
|
| 122 |
+
|
| 123 |
+
The temporary object to which the reference is bound or the temporary
|
| 124 |
+
object that is the complete object of a subobject to which the reference
|
| 125 |
+
is bound persists for the lifetime of the reference if the glvalue to
|
| 126 |
+
which the reference is bound was obtained through one of the following:
|
| 127 |
|
| 128 |
- a temporary materialization conversion [[conv.rval]],
|
| 129 |
- `(` *expression* `)`, where *expression* is one of these expressions,
|
| 130 |
- subscripting [[expr.sub]] of an array operand, where that operand is
|
| 131 |
one of these expressions,
|
|
|
|
| 164 |
|
| 165 |
— *end example*]
|
| 166 |
|
| 167 |
[*Note 5*:
|
| 168 |
|
| 169 |
+
An explicit type conversion [[expr.type.conv]], [[expr.cast]] is
|
| 170 |
interpreted as a sequence of elementary casts, covered above.
|
| 171 |
|
| 172 |
[*Example 3*:
|
| 173 |
|
| 174 |
``` cpp
|
|
|
|
| 211 |
`return` statement [[stmt.return]] is not extended; the temporary is
|
| 212 |
destroyed at the end of the full-expression in the `return` statement.
|
| 213 |
- A temporary bound to a reference in a *new-initializer* [[expr.new]]
|
| 214 |
persists until the completion of the full-expression containing the
|
| 215 |
*new-initializer*.
|
| 216 |
+
\[*Note 7*: This might introduce a dangling reference. — *end note*]
|
| 217 |
\[*Example 5*:
|
| 218 |
``` cpp
|
| 219 |
struct S { int mi; const std::pair<int,int>& mp; };
|
| 220 |
S a { 1, {2,3} };
|
| 221 |
S* p = new S{ 1, {2,3} }; // creates dangling reference
|
| 222 |
```
|
| 223 |
|
| 224 |
— *end example*]
|
| 225 |
|
| 226 |
+
The fourth context is when a temporary object other than a function
|
| 227 |
+
parameter object is created in the *for-range-initializer* of a
|
| 228 |
+
range-based `for` statement. If such a temporary object would otherwise
|
| 229 |
+
be destroyed at the end of the *for-range-initializer* full-expression,
|
| 230 |
+
the object persists for the lifetime of the reference initialized by the
|
| 231 |
+
*for-range-initializer*.
|
| 232 |
+
|
| 233 |
+
The destruction of a temporary whose lifetime is not extended beyond the
|
| 234 |
+
full-expression in which it was created is sequenced before the
|
| 235 |
+
destruction of every temporary which is constructed earlier in the same
|
| 236 |
+
full-expression. If the lifetime of two or more temporaries with
|
| 237 |
+
lifetimes extending beyond the full-expressions in which they were
|
| 238 |
+
created ends at the same point, these temporaries are destroyed at that
|
| 239 |
+
point in the reverse order of the completion of their construction. In
|
| 240 |
+
addition, the destruction of such temporaries shall take into account
|
| 241 |
+
the ordering of destruction of objects with static, thread, or automatic
|
| 242 |
+
storage duration
|
| 243 |
+
[[basic.stc.static]], [[basic.stc.thread]], [[basic.stc.auto]]; that is,
|
| 244 |
+
if `obj1` is an object with the same storage duration as the temporary
|
| 245 |
+
and created before the temporary is created the temporary shall be
|
| 246 |
+
destroyed before `obj1` is destroyed; if `obj2` is an object with the
|
| 247 |
+
same storage duration as the temporary and created after the temporary
|
| 248 |
+
is created the temporary shall be destroyed after `obj2` is destroyed.
|
| 249 |
|
| 250 |
[*Example 6*:
|
| 251 |
|
| 252 |
``` cpp
|
| 253 |
struct S {
|