Topic: Guarantee copy elision for complete objects returned
Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Wed, 30 May 2018 14:49:25 -0700 (PDT)
Raw View
------=_Part_264_1202075462.1527716965470
Content-Type: multipart/alternative;
boundary="----=_Part_265_2099752830.1527716965471"
------=_Part_265_2099752830.1527716965471
Content-Type: text/plain; charset="UTF-8"
*Proposal*
Copy/move elision for objects returned from a function is mandatory, even
if the move or copy constructors of that object have side-effects.
Foo getFoo() {
// code before foo definition
Foo foo(/*other args*/);
// code after foo definition
return foo; //Will result in copy elision
}
Further, the address of the returned object must be identical in the
function returning it and the calling function:
Foo* MY_GLOBAL_FOO_PTR;
Foo getFoo() {
// code before foo definition
Foo foo(/*other args*/);
// code after foo definition
MY_GLOBAL_FOO_PTR = &foo;
return foo; //Will result in copy elision
}
int main(){
Foo foo = getFoo();
//&foo == MY_GLOBAL_FOO_PTR after call to getFoo
}
*How this could kinda-sorta be achieved now*
This section is a demonstration that compilers have the capacity to do
this. Let's create a class that wraps a single instance of an arbitrary
type.
template<class T>
struct ElisionObj {
T value;
ElisionObj() : value {} {}
ElisionObj(const T& value) : value { value } {}
ElisionObj(T&& value) : value { std::move(value) } {}
ElisionObj(const ElisionObj& obj) = default;
ElisionObj(ElisionObj&& obj) = default;
template<class F, class... Args>
ElisionObj(F&& func, Args&&... args) : value { std::forward<decltype(args
)>(args)... } { func(value); }
operator T&() { return value; }
operator const T&() const { return value; }
};
Internally, returning foo by copy elision is identical to returning
ElisionObj<Foo> with the code after Foo's definition given as a closure to
the ElisionObj<Foo> constructor.
Foo* MY_GLOBAL_FOO_PTR;
ElisionObj<Foo> getFoo2() {
// code before foo definition
return ElisionObj<Foo>(
[&] (Foo& foo) {
// code after foo definition
},
/*other args*/
); //Currently results in copy elision under C++17 standard.
}
*Explanation*
ElisionObj<T> has (or can be trivially implemented with) the exact same
memory layout as T, and therefore the compiler may implement copy elision
for a complete object of type T in the same way that it would for an
ElisionObj<T>. The only situation where copy elision can't occur is when
returning a subobject, and thus *the only requirement for return with copy
elision is that the object being returned is a complete object. *
(I submitted another proposal for this, although that one imposed a
complicated set of restrictions I realized were unnecessary.)
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/93a53178-93b0-48ef-92c4-1f9b24130e1c%40isocpp.org.
------=_Part_265_2099752830.1527716965471
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><span style=3D"caret-color: rgb(102, 0, 102);"><b><fo=
nt color=3D"#444444">Proposal</font></b></span></div><div><span style=3D"ca=
ret-color: rgb(102, 0, 102);"><font color=3D"#444444">Copy/move elision for=
objects returned from a function is mandatory, even if the move or copy co=
nstructors of that object have side-effects.=C2=A0</font></span></div><div>=
<span style=3D"caret-color: rgb(102, 0, 102);"><font color=3D"#444444"><br>=
</font></span></div><div><span style=3D"caret-color: rgb(102, 0, 102);"><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Foo</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> getFoo</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
code before foo definition</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Foo</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">/*other args*/</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">// code after foo definition</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">//Will result in copy elision</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">}</span></div></code></div><br></span>Further, the addre=
ss of the returned object must be identical in the function returning it an=
d the calling function:</div><div><br></div><div><div class=3D"prettyprint"=
style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, =
187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint" style=3D"caret-color: rgb(102, 0, 102);"><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> MY_GLOBAL_FOO_PTR</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Foo</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> getFoo</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// cod=
e before foo definition</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Foo</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
*other args*/</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// code after foo definition</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 MY_GLOBAL_FOO_PTR </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//Wi=
ll result in copy elision</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><font color=3D"#660066"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(){</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Foo</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> foo </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> getFo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//&=
;foo =3D=3D MY_GLOBAL_FOO_PTR after call to getFoo</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">}</span></font></div></code></div><br><b>=
How this could kinda-sorta be achieved now</b></div><div>This section is a =
demonstration that compilers have the capacity to do this. Let's create=
a class that wraps a single instance of an arbitrary type.</div><div><br><=
/div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 18=
7, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><div style=3D"color: rgb(212, 212, 212); font-family: Menlo=
, Monaco, "Courier New", monospace; font-size: 12px; line-height:=
18px; white-space: pre; background-color: rgb(255, 255, 255);"><div><span =
style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">template</span></span><span style=3D"color: rgb(129, 19=
8, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan></span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color:=
#008;" class=3D"styled-by-prettify">class</span></span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(17=
4, 238, 149);"><span style=3D"color: #000;" class=3D"styled-by-prettify">T<=
/span></span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">></span></span></div><div><span s=
tyle=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">struct</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(174, 238, 149);">=
<span style=3D"color: #606;" class=3D"styled-by-prettify">ElisionObj</span>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span></div><div>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0T v=
alue</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0</span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"=
color: #606;" class=3D"styled-by-prettify">ElisionObj</span></span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> value </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{}</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(139, 238, 217);"><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">ElisionObj</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: rgb(129, 198, 190);"=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> value</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> value </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> value </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{}</span></div><div><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(139, 238, 217);"><span=
style=3D"color: #606;" class=3D"styled-by-prettify">ElisionObj</span></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"c=
olor: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&&</span></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> value</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> value </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: rgb(139, 238, 217);"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</s=
pan></span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">value</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{}</span></div><div><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb=
(139, 238, 217);"><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>ElisionObj</span></span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span></span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">ElisionObj</span><span style=3D"color: r=
gb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&</span></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> obj</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151, 145);">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">default</span></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div=
><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=
=A0</span><span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: =
#606;" class=3D"styled-by-prettify">ElisionObj</span></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">ElisionObj</span><span style=3D"color: rg=
b(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&&</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> obj</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151, 145=
);"><span style=3D"color: #008;" class=3D"styled-by-prettify">default</span=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
/div><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0=
=C2=A0</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">template</span></span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span></span><span style=3D"color: rgb(116, 151, 145);"=
><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: rgb(174, 238, 149);"><span style=3D"color: #000;" class=3D"=
styled-by-prettify">F</span></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">class</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Args</span><span style=3D"color: rgb(129, 19=
8, 190);"><span style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan></span></div><div><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> =C2=A0 =C2=A0</span><span style=3D"color: rgb(139, 238, 217);"><span =
style=3D"color: #606;" class=3D"styled-by-prettify">ElisionObj</span></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">F</span><span style=3D"co=
lor: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&&</span></span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> func</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
class=3D"styled-by-prettify">&&</span></span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> args</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v=
alue </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">forward</span><span style=3D=
"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-b=
y-prettify"><</span></span><span style=3D"color: rgb(139, 238, 217);"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ar=
gs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: rgb(139, 238, 217);"=
><span style=3D"color: #000;" class=3D"styled-by-prettify">func</span></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">value</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">}</span></div><div><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: =
rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">operator</span></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> T</span><span style=3D"color: rgb(129, 198, 190);"><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&</span></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151, 145);"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">return</span></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> value</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span></div><div><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D=
"color: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">operator</span></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(116, 151, 145);"><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">const</span></span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&</span></span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">const</span></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(116, 151, 14=
5);"><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> value</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span></div><div><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span></div></div></div><=
/code></div><br>Internally, returning foo by copy elision is identical to r=
eturning ElisionObj<Foo> with the code after Foo's definition giv=
en as a closure to the ElisionObj<Foo> constructor. =C2=A0</div><div>=
<br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> MY_GLOBAL_FOO_PTR</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">ElisionObj</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Foo</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
getFoo2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// </span><span styl=
e=3D"caret-color: rgb(102, 0, 102); color: rgb(136, 0, 0);"><span style=3D"=
color: #800;" class=3D"styled-by-prettify">code before foo definition</span=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">ElisionObj</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[&=
]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">// </span><span style=3D"caret-color=
: rgb(102, 0, 102); color: rgb(136, 0, 0);"><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">code after foo definition</span></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">},<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0=
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">/*other args*/</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><font color=3D"#666600"><span style=3D"color: #800;=
" class=3D"styled-by-prettify">//Currently results in copy elision under C+=
+17 standard. </span></font><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">}</span><font color=3D"#660066" style=3D"caret-color: rgb(102, 0, 102)=
;"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></f=
ont></div></code></div><div><br></div><b>Explanation</b><br>ElisionObj<T=
> has (or can be trivially implemented with) the exact same memory layou=
t as T, and therefore the compiler may implement copy elision for a complet=
e object of type T in the same way that it would for an ElisionObj<T>=
.. The only situation where copy elision can't occur is when returning a=
subobject, and thus <b>the only requirement for return with copy elision i=
s that the object being returned is a complete object.=C2=A0</b></div><div>=
<br></div>(I submitted another proposal for this, although that one imposed=
a complicated set of restrictions I realized were unnecessary.)</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/93a53178-93b0-48ef-92c4-1f9b24130e1c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/93a53178-93b0-48ef-92c4-1f9b24130e1c=
%40isocpp.org</a>.<br />
------=_Part_265_2099752830.1527716965471--
------=_Part_264_1202075462.1527716965470--
.