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">&amp;</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">//&amp=
;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&#39;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, &quot;Courier New&quot;, 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">&lt;</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">&gt;</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">&amp;</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">&amp;&amp;</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">&amp;</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=
">&amp;&amp;</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">&lt;</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">&gt;</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">&amp;&amp;</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">&amp;&amp;</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">&lt;</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">&gt;</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">&amp;</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">&amp;</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&lt;Foo&gt; with the code after Foo&#39;s definition giv=
en as a closure to the ElisionObj&lt;Foo&gt; 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">&lt;</span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Foo</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&gt;</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">&lt;</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</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">[&amp;=
]</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">&amp;</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&lt;T=
&gt; 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&lt;T&gt;=
.. The only situation where copy elision can&#39;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&quot; 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--

.