Topic: Preferring operator=(T&& rhs) over operator(T rhs)


Author: oguzakyuz@gmail.com
Date: Thu, 12 Apr 2018 23:11:20 -0700 (PDT)
Raw View
------=_Part_7787_705968762.1523599880709
Content-Type: multipart/alternative;
 boundary="----=_Part_7788_969848714.1523599880710"

------=_Part_7788_969848714.1523599880710
Content-Type: text/plain; charset="UTF-8"

Let me know if this is a stupid idea or something that is already
considered. But to my knowledge, if we have the following operator
overloads for a class, compilers will generate an ambiguity error (probably
enforced by the standard):

C& C::operator=(C rhs);
C& C::operator=(C&& rhs);

However, if the compilers could choose the rvalue reference version over the pass-by-value version for rvalue arguments (i.e. c2 = c1 + c1), it could lead to an efficient copy-swap idiom implementation.

Below is a sample code that demonstrates the problem. The issue is explained by the long comment block inside the main function:


#include <algorithm>

class C
{
    int* data;

     public:

     C() : data(nullptr) { }

     C(int data) : data(new int)
     {
         *(this->data) = data;
     }

     C(const C& rhs) : data(new int)
     {
         *data = *(rhs.data);
     }

     C(C&& rhs) : C()
     {
         // Move constructor is first creating a default
         // object and swapping it with the rvalue reference.
         swap(*this, rhs);
     }

     C& operator=(C rhs)
     {
         // We let the compiler copy into rhs and we swap the
         // current object with this copy. Together with the
         // move constructor above, this implements the copy-swap
         // idiom. Thanks to the move-constructor above, the
         // copy to rhs is not a deep copy if the input is an rvalue
         // reference.
         swap(*this, rhs);
         return *this;
     }

     // The function below is commented out because it fails compilation
     // due to ambiguity with the above function. However, if it worked
     // it could have saved us an extra call to the move constructor when
     // we make calls such as c2 = c1 + c1 (see operator+ below). If it had
     // worked, the temporary created from c1 + c1 would have been directly
     // taken by rvalue reference instead of its copy  (albeit shallow)
being
     // created.

     /*
     C& operator=(C&& rhs)
     {
         swap(*this, rhs);
         return *this;
     }
     */

     C operator+(const C& rhs)
     {
         C result(*data + *(rhs.data));
         return result;
     }

     friend void swap(C& lhs, C& rhs);

     ~C()
     {
         delete data;
     }
};

void swap(C& lhs, C& rhs)
{
    std::swap(lhs.data, rhs.data);
}

int main()
{
    C c1(7);
    C c2;

    // The following will first create the "result" inside operator+.
    // The return value will then get move-constructed from the result
    // (I'm assuming that -fno-elide-constructors option is used). Then
    // the "rhs" parameter of operator= will get move-constructed from
    // this return temporary.
    //
    // But if we could overload operator=(C&&), this second
move-construction
    // could have been avoided as the return temporary could have been
directly
    // captured by rvalue reference.
    //
    // Granted that we can implement operator=(const C&) and operator=(C&&)
    // to make assignment as efficient as possible for both lvalue and
rvalue
    // inputs. However, to my knowledge, having operator=(const C&) would
    // essentially prevent us from having the copy-swap idiom.

    c2 = c1 + c1;

    return 0;
}


--
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/62809333-fd1a-4bde-8805-ccc0578a4284%40isocpp.org.

------=_Part_7788_969848714.1523599880710
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Let me know if this is a stupid idea or something that is =
already considered. But to my knowledge, if we have the following operator =
overloads for a class, compilers will generate an ambiguity error (probably=
 enforced by the standard):<br><br><pre class=3D"lang-cpp prettyprint prett=
yprinted" style=3D""><code><span class=3D"pln">C</span><span class=3D"pun">=
&amp;</span><span class=3D"pln"> C::</span><span class=3D"kwd">operator</sp=
an><span class=3D"pun">=3D(</span><span class=3D"pln">C rhs</span><span cla=
ss=3D"pun">);<br></span></code><code><span class=3D"pln">C</span><span clas=
s=3D"pun">&amp;</span><span class=3D"pln"> C::</span><span class=3D"kwd">op=
erator</span><span class=3D"pun">=3D(</span><span class=3D"pln">C&amp;&amp;=
 rhs</span><span class=3D"pun">);</span></code><br><br>However, if the comp=
ilers could choose the rvalue reference version over the pass-by-value vers=
ion for rvalue arguments (i.e. c2 =3D c1 + c1), it could lead to an efficie=
nt copy-swap idiom implementation.<br><br>Below is a sample code that demon=
strates the problem. The issue is explained by the long comment block insid=
e the main function:<br><code><span class=3D"pun"></span></code></pre><br><=
div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 1=
87, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word=
;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">#include =
&lt;algorithm&gt;<br><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> C<br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</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-prett=
ify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> data</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color: #008;" class=3D"styled-by-prettify">public<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=
=A0 =C2=A0C</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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> data</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">nullptr</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
=C2=A0 =C2=A0 =C2=A0C</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> data=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan 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"> data</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">new</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">int</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</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*(</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">this</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">-&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">data</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">=3D</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> data</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</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0C</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> rhs</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 style=3D"color: #000;" class=3D"styled-by-prettify=
"> data</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">new</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=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 =C2=
=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">data </span><spa=
n style=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=
: #660;" class=3D"styled-by-prettify">*(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">rhs</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">data</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><br>=C2=A0 =C2=A0 =C2=A0C</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">C</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> rhs</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=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 =C2=
=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Move=
 constructor is first creating a default</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// object and swa=
pping it with the rvalue reference.</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0swap</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">this</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0</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><br>=C2=A0 =C2=A0 =C2=A0C</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">C rhs</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=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"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">// We let the compiler copy into=
 rhs and we swap the</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// current object with this copy. Tog=
ether with the</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// move constructor above, this implements =
the copy-swap</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// idiom. Thanks to the move-constructor abo=
ve, the</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">// copy to rhs is not a deep copy if the input is =
an rvalue<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // reference.=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0swap</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(*</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> rhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">*</span><span style=3D"color: #008;" class=3D"styled-by-prettify">this<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></spa=
n>=C2=A0=C2=A0=C2=A0=C2=A0 // The function below is commented out because i=
t fails compilation<br>=C2=A0=C2=A0=C2=A0=C2=A0 // due to ambiguity with th=
e above function. However, if it worked<br>=C2=A0=C2=A0=C2=A0=C2=A0 // it c=
ould have saved us an extra call to the move constructor when<br>=C2=A0=C2=
=A0=C2=A0=C2=A0 // we make calls such as c2 =3D c1 + c1 (see operator+ belo=
w). If it had<br>=C2=A0=C2=A0=C2=A0=C2=A0 // worked, the temporary created =
from c1 + c1 would have been directly <br>=C2=A0=C2=A0=C2=A0=C2=A0 // taken=
 by rvalue reference instead of its copy=C2=A0 (albeit shallow) being<br>=
=C2=A0=C2=A0=C2=A0=C2=A0 // created. <br>=C2=A0=C2=A0=C2=A0=C2=A0 <br>=C2=
=A0=C2=A0=C2=A0=C2=A0 /*<br><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">=C2=A0=C2=A0=C2=A0=C2=A0 C</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">C&amp;&amp; rhs</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=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: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0swap</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(*</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">this</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> rhs</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</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: #008;" class=3D"styled-by=
-prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=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 */<br></span></code><br>=C2=A0 =C2=A0 =C2=A0C=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">+(</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> rhs</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</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 =C2=A0C result=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">data </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;" cla=
ss=3D"styled-by-prettify">rhs</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">data</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> result</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=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"style=
d-by-prettify"><br><br>=C2=A0</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">=C2=A0=C2=A0=C2=A0 friend</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> swap</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">C</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> lhs</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><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">C</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</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=C2=A0=C2=A0=C2=A0 {</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 d=
elete</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> data=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan 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"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> swap</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">C</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> lhs</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> C</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> rhs</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0=C2=A0=C2=A0 std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">swap</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">lhs</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">data</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> rhs<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">data</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cla=
ss=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-pretti=
fy"><br></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 C c1</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">7<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=C2=A0=C2=
=A0 C c2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0=C2=A0=
=C2=A0 // The following will first create the &quot;result&quot; inside ope=
rator+.<br>=C2=A0 =C2=A0 // The return value will then get move-constructed=
 from the result<br>=C2=A0=C2=A0=C2=A0 // (I&#39;m assuming that -fno-elide=
-constructors option is used). Then<br>=C2=A0=C2=A0=C2=A0 // the &quot;rhs&=
quot; parameter of operator=3D will get move-constructed from<br>=C2=A0=C2=
=A0=C2=A0 // this return temporary.<br>=C2=A0=C2=A0=C2=A0 //<br>=C2=A0=C2=
=A0=C2=A0 // But if we could overload operator=3D(C&amp;&amp;), this second=
 move-construction<br>=C2=A0=C2=A0=C2=A0 // could have been avoided as the =
return temporary could have been directly<br>=C2=A0=C2=A0=C2=A0 // captured=
 by rvalue reference.<br>=C2=A0=C2=A0=C2=A0 //<br>=C2=A0=C2=A0=C2=A0 // Gra=
nted that we can implement operator=3D(const C&amp;) and operator=3D(C&amp;=
&amp;)<br>=C2=A0=C2=A0=C2=A0 // to make assignment as efficient as possible=
 for both lvalue and rvalue<br>=C2=A0=C2=A0=C2=A0 // inputs. However, to my=
 knowledge, having operator=3D(const C&amp;) would<br>=C2=A0=C2=A0=C2=A0 //=
 essentially prevent us from having the copy-swap idiom.<br><br>=C2=A0=C2=
=A0=C2=A0 c2 </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c1 =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> c1</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">=C2=A0=C2=A0 return</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><br><br></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/62809333-fd1a-4bde-8805-ccc0578a4284%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/62809333-fd1a-4bde-8805-ccc0578a4284=
%40isocpp.org</a>.<br />

------=_Part_7788_969848714.1523599880710--

------=_Part_7787_705968762.1523599880709--

.