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">=
&</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">&</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&&=
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 =
<algorithm><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">-></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">&</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">&&</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">&</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">&</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&& 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">&</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">&=
;</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">&</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">&</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">&</=
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 "result" 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'm assuming that -fno-elide=
-constructors option is used). Then<br>=C2=A0=C2=A0=C2=A0 // the "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&&), 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&) and operator=3D(C&=
&)<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&) 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" 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--
.