tmp/tmpblywn19a/{from.md → to.md}
RENAMED
|
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
### Copy/move elision <a id="class.copy.elision">[[class.copy.elision]]</a>
|
| 2 |
+
|
| 3 |
+
When certain criteria are met, an implementation is allowed to omit the
|
| 4 |
+
copy/move construction of a class object, even if the constructor
|
| 5 |
+
selected for the copy/move operation and/or the destructor for the
|
| 6 |
+
object have side effects. In such cases, the implementation treats the
|
| 7 |
+
source and target of the omitted copy/move operation as simply two
|
| 8 |
+
different ways of referring to the same object. If the first parameter
|
| 9 |
+
of the selected constructor is an rvalue reference to the object’s type,
|
| 10 |
+
the destruction of that object occurs when the target would have been
|
| 11 |
+
destroyed; otherwise, the destruction occurs at the later of the times
|
| 12 |
+
when the two objects would have been destroyed without the
|
| 13 |
+
optimization.[^7] This elision of copy/move operations, called *copy
|
| 14 |
+
elision*, is permitted in the following circumstances (which may be
|
| 15 |
+
combined to eliminate multiple copies):
|
| 16 |
+
|
| 17 |
+
- in a `return` statement in a function with a class return type, when
|
| 18 |
+
the *expression* is the name of a non-volatile automatic object (other
|
| 19 |
+
than a function parameter or a variable introduced by the
|
| 20 |
+
*exception-declaration* of a *handler* ([[except.handle]])) with the
|
| 21 |
+
same type (ignoring cv-qualification) as the function return type, the
|
| 22 |
+
copy/move operation can be omitted by constructing the automatic
|
| 23 |
+
object directly into the function call’s return object
|
| 24 |
+
- in a *throw-expression* ([[expr.throw]]), when the operand is the
|
| 25 |
+
name of a non-volatile automatic object (other than a function or
|
| 26 |
+
catch-clause parameter) whose scope does not extend beyond the end of
|
| 27 |
+
the innermost enclosing *try-block* (if there is one), the copy/move
|
| 28 |
+
operation from the operand to the exception object ([[except.throw]])
|
| 29 |
+
can be omitted by constructing the automatic object directly into the
|
| 30 |
+
exception object
|
| 31 |
+
- when the *exception-declaration* of an exception handler (Clause
|
| 32 |
+
[[except]]) declares an object of the same type (except for
|
| 33 |
+
cv-qualification) as the exception object ([[except.throw]]), the
|
| 34 |
+
copy operation can be omitted by treating the *exception-declaration*
|
| 35 |
+
as an alias for the exception object if the meaning of the program
|
| 36 |
+
will be unchanged except for the execution of constructors and
|
| 37 |
+
destructors for the object declared by the *exception-declaration*.
|
| 38 |
+
\[*Note 1*: There cannot be a move from the exception object because
|
| 39 |
+
it is always an lvalue. — *end note*]
|
| 40 |
+
|
| 41 |
+
Copy elision is required where an expression is evaluated in a context
|
| 42 |
+
requiring a constant expression ([[expr.const]]) and in constant
|
| 43 |
+
initialization ([[basic.start.static]]).
|
| 44 |
+
|
| 45 |
+
[*Note 2*: Copy elision might not be performed if the same expression
|
| 46 |
+
is evaluated in another context. — *end note*]
|
| 47 |
+
|
| 48 |
+
[*Example 1*:
|
| 49 |
+
|
| 50 |
+
``` cpp
|
| 51 |
+
class Thing {
|
| 52 |
+
public:
|
| 53 |
+
Thing();
|
| 54 |
+
~Thing();
|
| 55 |
+
Thing(const Thing&);
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
Thing f() {
|
| 59 |
+
Thing t;
|
| 60 |
+
return t;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
Thing t2 = f();
|
| 64 |
+
|
| 65 |
+
struct A {
|
| 66 |
+
void *p;
|
| 67 |
+
constexpr A(): p(this) {}
|
| 68 |
+
};
|
| 69 |
+
|
| 70 |
+
constexpr A g() {
|
| 71 |
+
A a;
|
| 72 |
+
return a;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
constexpr A a; // well-formed, a.p points to a
|
| 76 |
+
constexpr A b = g(); // well-formed, b.p points to b
|
| 77 |
+
|
| 78 |
+
void g() {
|
| 79 |
+
A c = g(); // well-formed, c.p may point to c or to an ephemeral temporary
|
| 80 |
+
}
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
Here the criteria for elision can eliminate the copying of the local
|
| 84 |
+
automatic object `t` into the result object for the function call `f()`,
|
| 85 |
+
which is the global object `t2`. Effectively, the construction of the
|
| 86 |
+
local object `t` can be viewed as directly initializing the global
|
| 87 |
+
object `t2`, and that object’s destruction will occur at program exit.
|
| 88 |
+
Adding a move constructor to `Thing` has the same effect, but it is the
|
| 89 |
+
move construction from the local automatic object to `t2` that is
|
| 90 |
+
elided.
|
| 91 |
+
|
| 92 |
+
— *end example*]
|
| 93 |
+
|
| 94 |
+
In the following copy-initialization contexts, a move operation might be
|
| 95 |
+
used instead of a copy operation:
|
| 96 |
+
|
| 97 |
+
- If the *expression* in a `return` statement ([[stmt.return]]) is a
|
| 98 |
+
(possibly parenthesized) *id-expression* that names an object with
|
| 99 |
+
automatic storage duration declared in the body or
|
| 100 |
+
*parameter-declaration-clause* of the innermost enclosing function or
|
| 101 |
+
*lambda-expression*, or
|
| 102 |
+
- if the operand of a *throw-expression* ([[expr.throw]]) is the name
|
| 103 |
+
of a non-volatile automatic object (other than a function or
|
| 104 |
+
catch-clause parameter) whose scope does not extend beyond the end of
|
| 105 |
+
the innermost enclosing *try-block* (if there is one),
|
| 106 |
+
|
| 107 |
+
overload resolution to select the constructor for the copy is first
|
| 108 |
+
performed as if the object were designated by an rvalue. If the first
|
| 109 |
+
overload resolution fails or was not performed, or if the type of the
|
| 110 |
+
first parameter of the selected constructor is not an rvalue reference
|
| 111 |
+
to the object’s type (possibly cv-qualified), overload resolution is
|
| 112 |
+
performed again, considering the object as an lvalue.
|
| 113 |
+
|
| 114 |
+
[*Note 3*: This two-stage overload resolution must be performed
|
| 115 |
+
regardless of whether copy elision will occur. It determines the
|
| 116 |
+
constructor to be called if elision is not performed, and the selected
|
| 117 |
+
constructor must be accessible even if the call is
|
| 118 |
+
elided. — *end note*]
|
| 119 |
+
|
| 120 |
+
[*Example 2*:
|
| 121 |
+
|
| 122 |
+
``` cpp
|
| 123 |
+
class Thing {
|
| 124 |
+
public:
|
| 125 |
+
Thing();
|
| 126 |
+
~Thing();
|
| 127 |
+
Thing(Thing&&);
|
| 128 |
+
private:
|
| 129 |
+
Thing(const Thing&);
|
| 130 |
+
};
|
| 131 |
+
|
| 132 |
+
Thing f(bool b) {
|
| 133 |
+
Thing t;
|
| 134 |
+
if (b)
|
| 135 |
+
throw t; // OK: Thing(Thing&&) used (or elided) to throw t
|
| 136 |
+
return t; // OK: Thing(Thing&&) used (or elided) to return t
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
Thing t2 = f(false); // OK: no extra copy/move performed, t2 constructed by call to f
|
| 140 |
+
|
| 141 |
+
struct Weird {
|
| 142 |
+
Weird();
|
| 143 |
+
Weird(Weird&);
|
| 144 |
+
};
|
| 145 |
+
|
| 146 |
+
Weird g() {
|
| 147 |
+
Weird w;
|
| 148 |
+
return w; // OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
|
| 149 |
+
}
|
| 150 |
+
```
|
| 151 |
+
|
| 152 |
+
— *end example*]
|
| 153 |
+
|
| 154 |
+
<!-- Link reference definitions -->
|
| 155 |
+
[basic.def.odr]: basic.md#basic.def.odr
|
| 156 |
+
[basic.life]: basic.md#basic.life
|
| 157 |
+
[basic.lookup]: basic.md#basic.lookup
|
| 158 |
+
[basic.lval]: basic.md#basic.lval
|
| 159 |
+
[basic.start.dynamic]: basic.md#basic.start.dynamic
|
| 160 |
+
[basic.start.static]: basic.md#basic.start.static
|
| 161 |
+
[basic.start.term]: basic.md#basic.start.term
|
| 162 |
+
[basic.stc.auto]: basic.md#basic.stc.auto
|
| 163 |
+
[basic.stc.dynamic]: basic.md#basic.stc.dynamic
|
| 164 |
+
[basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
|
| 165 |
+
[basic.stc.static]: basic.md#basic.stc.static
|
| 166 |
+
[basic.stc.thread]: basic.md#basic.stc.thread
|
| 167 |
+
[basic.types]: basic.md#basic.types
|
| 168 |
+
[class]: class.md#class
|
| 169 |
+
[class.abstract]: class.md#class.abstract
|
| 170 |
+
[class.access]: class.md#class.access
|
| 171 |
+
[class.base.init]: #class.base.init
|
| 172 |
+
[class.cdtor]: #class.cdtor
|
| 173 |
+
[class.conv]: #class.conv
|
| 174 |
+
[class.conv.ctor]: #class.conv.ctor
|
| 175 |
+
[class.conv.fct]: #class.conv.fct
|
| 176 |
+
[class.copy]: #class.copy
|
| 177 |
+
[class.copy.assign]: #class.copy.assign
|
| 178 |
+
[class.copy.ctor]: #class.copy.ctor
|
| 179 |
+
[class.copy.elision]: #class.copy.elision
|
| 180 |
+
[class.ctor]: #class.ctor
|
| 181 |
+
[class.dtor]: #class.dtor
|
| 182 |
+
[class.expl.init]: #class.expl.init
|
| 183 |
+
[class.free]: #class.free
|
| 184 |
+
[class.friend]: class.md#class.friend
|
| 185 |
+
[class.inhctor.init]: #class.inhctor.init
|
| 186 |
+
[class.init]: #class.init
|
| 187 |
+
[class.mem]: class.md#class.mem
|
| 188 |
+
[class.member.lookup]: class.md#class.member.lookup
|
| 189 |
+
[class.mfct]: class.md#class.mfct
|
| 190 |
+
[class.mi]: class.md#class.mi
|
| 191 |
+
[class.qual]: basic.md#class.qual
|
| 192 |
+
[class.temporary]: #class.temporary
|
| 193 |
+
[class.union]: class.md#class.union
|
| 194 |
+
[class.union.anon]: class.md#class.union.anon
|
| 195 |
+
[class.virtual]: class.md#class.virtual
|
| 196 |
+
[conv]: conv.md#conv
|
| 197 |
+
[conv.array]: conv.md#conv.array
|
| 198 |
+
[conv.rval]: conv.md#conv.rval
|
| 199 |
+
[dcl.array]: dcl.md#dcl.array
|
| 200 |
+
[dcl.constexpr]: dcl.md#dcl.constexpr
|
| 201 |
+
[dcl.fct]: dcl.md#dcl.fct
|
| 202 |
+
[dcl.fct.def]: dcl.md#dcl.fct.def
|
| 203 |
+
[dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
|
| 204 |
+
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 205 |
+
[dcl.fct.spec]: dcl.md#dcl.fct.spec
|
| 206 |
+
[dcl.init]: dcl.md#dcl.init
|
| 207 |
+
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 208 |
+
[dcl.init.list]: dcl.md#dcl.init.list
|
| 209 |
+
[dcl.init.ref]: dcl.md#dcl.init.ref
|
| 210 |
+
[dcl.spec.auto]: dcl.md#dcl.spec.auto
|
| 211 |
+
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 212 |
+
[diff.special]: compatibility.md#diff.special
|
| 213 |
+
[except]: except.md#except
|
| 214 |
+
[except.ctor]: except.md#except.ctor
|
| 215 |
+
[except.handle]: except.md#except.handle
|
| 216 |
+
[except.spec]: except.md#except.spec
|
| 217 |
+
[except.throw]: except.md#except.throw
|
| 218 |
+
[expr]: expr.md#expr
|
| 219 |
+
[expr.ass]: expr.md#expr.ass
|
| 220 |
+
[expr.call]: expr.md#expr.call
|
| 221 |
+
[expr.cast]: expr.md#expr.cast
|
| 222 |
+
[expr.const]: expr.md#expr.const
|
| 223 |
+
[expr.const.cast]: expr.md#expr.const.cast
|
| 224 |
+
[expr.delete]: expr.md#expr.delete
|
| 225 |
+
[expr.dynamic.cast]: expr.md#expr.dynamic.cast
|
| 226 |
+
[expr.mptr.oper]: expr.md#expr.mptr.oper
|
| 227 |
+
[expr.new]: expr.md#expr.new
|
| 228 |
+
[expr.prim]: expr.md#expr.prim
|
| 229 |
+
[expr.prim.lambda.capture]: expr.md#expr.prim.lambda.capture
|
| 230 |
+
[expr.pseudo]: expr.md#expr.pseudo
|
| 231 |
+
[expr.ref]: expr.md#expr.ref
|
| 232 |
+
[expr.sizeof]: expr.md#expr.sizeof
|
| 233 |
+
[expr.static.cast]: expr.md#expr.static.cast
|
| 234 |
+
[expr.sub]: expr.md#expr.sub
|
| 235 |
+
[expr.throw]: expr.md#expr.throw
|
| 236 |
+
[expr.type.conv]: expr.md#expr.type.conv
|
| 237 |
+
[expr.typeid]: expr.md#expr.typeid
|
| 238 |
+
[expr.unary.op]: expr.md#expr.unary.op
|
| 239 |
+
[intro.execution]: intro.md#intro.execution
|
| 240 |
+
[intro.object]: intro.md#intro.object
|
| 241 |
+
[namespace.udecl]: dcl.md#namespace.udecl
|
| 242 |
+
[over.ass]: over.md#over.ass
|
| 243 |
+
[over.best.ics]: over.md#over.best.ics
|
| 244 |
+
[over.ics.ref]: over.md#over.ics.ref
|
| 245 |
+
[over.match]: over.md#over.match
|
| 246 |
+
[over.match.best]: over.md#over.match.best
|
| 247 |
+
[over.match.copy]: over.md#over.match.copy
|
| 248 |
+
[over.over]: over.md#over.over
|
| 249 |
+
[special]: #special
|
| 250 |
+
[stmt.dcl]: stmt.md#stmt.dcl
|
| 251 |
+
[stmt.return]: stmt.md#stmt.return
|
| 252 |
+
[temp.dep.type]: temp.md#temp.dep.type
|
| 253 |
+
[temp.variadic]: temp.md#temp.variadic
|
| 254 |
+
|
| 255 |
+
[^1]: The same rules apply to initialization of an `initializer_list`
|
| 256 |
+
object ([[dcl.init.list]]) with its underlying temporary array.
|
| 257 |
+
|
| 258 |
+
[^2]: These conversions are considered as standard conversions for the
|
| 259 |
+
purposes of overload resolution ([[over.best.ics]],
|
| 260 |
+
[[over.ics.ref]]) and therefore initialization ([[dcl.init]]) and
|
| 261 |
+
explicit casts ([[expr.static.cast]]). A conversion to `void` does
|
| 262 |
+
not invoke any conversion function ([[expr.static.cast]]). Even
|
| 263 |
+
though never directly called to perform a conversion, such
|
| 264 |
+
conversion functions can be declared and can potentially be reached
|
| 265 |
+
through a call to a virtual conversion function in a base class.
|
| 266 |
+
|
| 267 |
+
[^3]: A similar provision is not needed for the array version of
|
| 268 |
+
`operator` `delete` because [[expr.delete]] requires that in this
|
| 269 |
+
situation, the static type of the object to be deleted be the same
|
| 270 |
+
as its dynamic type.
|
| 271 |
+
|
| 272 |
+
[^4]: This implies that the reference parameter of the
|
| 273 |
+
implicitly-declared copy constructor cannot bind to a `volatile`
|
| 274 |
+
lvalue; see [[diff.special]].
|
| 275 |
+
|
| 276 |
+
[^5]: Because a template assignment operator or an assignment operator
|
| 277 |
+
taking an rvalue reference parameter is never a copy assignment
|
| 278 |
+
operator, the presence of such an assignment operator does not
|
| 279 |
+
suppress the implicit declaration of a copy assignment operator.
|
| 280 |
+
Such assignment operators participate in overload resolution with
|
| 281 |
+
other assignment operators, including copy assignment operators,
|
| 282 |
+
and, if selected, will be used to assign an object.
|
| 283 |
+
|
| 284 |
+
[^6]: This implies that the reference parameter of the
|
| 285 |
+
implicitly-declared copy assignment operator cannot bind to a
|
| 286 |
+
`volatile` lvalue; see [[diff.special]].
|
| 287 |
+
|
| 288 |
+
[^7]: Because only one object is destroyed instead of two, and one
|
| 289 |
+
copy/move constructor is not executed, there is still one object
|
| 290 |
+
destroyed for each one constructed.
|