Topic: std::sink<T> - always pass sink arguments efficiently
Author: vittorio.romeo.vee@gmail.com
Date: Tue, 10 Sep 2013 06:42:08 -0700 (PDT)
Raw View
------=_Part_199_28896140.1378820528515
Content-Type: text/plain; charset=ISO-8859-1
Inspired by my own StackOverflow question.<http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments>
Problem: passing sink arguments efficiently requires either a lot of code
duplication or performance trade-offs.
Thanks to move semantics in C++11, we can now efficiently move large
objects.
In many occasions we require to pass a *sink argument, *which is an
argument that will get stored somewhere, or it will be used then
immediately discarded.
Here's the most common example: initializing a class instance with an
std::string.
*
*
*
*
*Approach 1: pass by value + std::move*
struct Example {
std::string s;
Example(std::string mS) : s{std::move(mS)} { }
};
If *mS *is a temporary: the value is initialized from the temporary by
moving, and then you yourself move from the argument, thus no copy is made.
*Result: **1 move*
If *mS* is an lvalue: you copy it in the argument and then move from it,
thus a single copy + move is made.
*Result: **1 copy + 1 move*
*
*
*
*
*
*
*Approa**ch 2: have two constructors (one by const&, one by &&)*
struct Example {
std::string s;
Example(std::string&& mS) : s{std::move(mS)} { } // ctor 1
Example(const std::string& mS) : s{mS} { } // ctor 2
};
If *mS *is a temporary: ctor 1 is called. No copy is made. Only the move
constructor for mS is called.
*Result: **1 move*
If *mS* is an lvalue: you copy it in the argument, thus a single copy is
made.
*Result: **1 copy*
*Additional benefit*:
> No additional code is generated on the caller's side! The calling of the
> copy- or move-constructor (which might be inlined or not) can now live in
> the implementation of the called function (here: Test::Test) and therefore
> only a single copy of that code is required. If you use by-value parameter
> passing, the caller is responsible for producing the object that is passed
> to the function.
As you can see, *Approach 2 *has the most efficient results and generates
the best possible code. It has one major drawback: code duplication.
You have to write *n^2 *constructors for *all possible combinations of
const& and &&*.
struct Example {
std::string s1, s2;
Example(std::string&& mS1, std::string&& mS2) : s1{std::move(
mS1)}, s2{std::move(mS2)} { }
Example(const std::string& mS1, std::string&& mS2) : s1{mS1}, s2{
std::move(mS2)} { }
Example(std::string&& mS1, const std::string& mS2) : s1{std::move(
mS1)}, s2{mS2} { }
Example(const std::string& mS1, const std::string& mS2) : s1{mS1}, s2{
mS2} { }
};
Proposal: add *std::sink<T>*, which automatically performs the best
possible action, depending on whether T is a const& or an &&
struct Example {
std::string s1, s2;
Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{mS1
}, s2{mS2} { }
};
It should behave exactly *as if* four constructors (n^2) were written, like
in the* Approach 2* example.
*std::sink<T> *would allow the developer to not call any unnecessary
constructors and to not write n^2 constructors/functions. *No
performance trade-off, no code duplication.*
Thoughts?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_199_28896140.1378820528515
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><a href=3D"http://stackoverflow.com/questions/18673658/sho=
uld-i-always-move-on-sink-constructor-or-setter-arguments">Inspired by my o=
wn StackOverflow question.</a><div><br></div><div><font size=3D"6">Problem:=
passing sink arguments efficiently requires either a lot of code duplicati=
on or performance trade-offs.</font></div><div><br></div><div>Thanks t=
o move semantics in C++11, we can now efficiently move large objects. =
</div><div>In many occasions we require to pass a <i>sink argument, </i>whi=
ch is an argument that will get stored somewhere, or it will be used then i=
mmediately discarded.</div><div><br></div><div>Here's the most common examp=
le: initializing a class instance with an std::string.</div><div><br></div>=
<div><b><br></b></div><div><b><br></b></div><div><b>Approach 1: pass by val=
ue + std::move</b></div><div><div class=3D"prettyprint" style=3D"border: 1p=
x solid rgb(187, 187, 187); background-color: rgb(250, 250, 250); word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Example</span><font color=3D"#66=
6600"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> s</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Example</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">string</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> mS</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: #000;" class=3D"styled-by-prettify"> s</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>mS</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)}</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=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"><br></span></font><font color=3D"#666600"><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">};</span></font></div></co=
de></div></div><div>If <b>mS </b>is a temporary: the value is initialized f=
rom the temporary by moving, and then you yourself move from the argument, =
thus no copy is made.</div><div><i>Result: </i><b>1 move</b></div><div><br>=
</div><div>If <b>mS</b> is an lvalue: you copy it in the argument and =
then move from it, thus a single copy + move is made.</div><div><i>Result: =
</i><b>1 copy + 1 move</b></div><div><b><br></b></div><div><b><br></b></div=
><div><b><br></b></div><div><b>Approa</b><b>ch 2: have two constructors (on=
e by const&, one by &&)</b></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"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Example</s=
pan><font color=3D"#666600"><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"><br>&nb=
sp; std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">stri=
ng</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Example</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> mS</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"> s</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">move</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">mS</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"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// ctor 1</span><font color=3D"#666600"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Example</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">string</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> mS</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"> s</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">mS</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: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> &n=
bsp; </span><span style=3D"color: #800;" class=3D"styled-by-p=
rettify">// ctor 2</span></font><font color=3D"#666600"><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">};</span></font></div></code></div><div>If=
<b>mS </b>is a temporary: ctor 1 is called. No copy is made=
.. Only the move constructor for mS is called.</div><div><i>Result: </i=
><b>1 move</b></div><div><br></div><div>If <b>mS</b> is an lvalue=
: you copy it in the argument, thus a single copy is made.</div><div><=
i>Result: </i><b>1 copy</b></div><br></div><div><i>Additional benefit<=
/i>:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.=
8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-=
left-style: solid; padding-left: 1ex;">No additional code is generated on t=
he caller's side! The calling of the copy- or move-constructor (which might=
be inlined or not) can now live in the implementation of the called functi=
on (here: Test::Test) and therefore only a single copy of that code is requ=
ired. If you use by-value parameter passing, the caller is responsible for =
producing the object that is passed to the function.</blockquote><div><br><=
/div><div><span style=3D"font-size: 13px;"><br></span></div><div><span styl=
e=3D"font-size: 13px;"><br></span></div><div><span style=3D"font-size: 13px=
;">As you can see, <b>Approach 2 </b>has the most efficient results and gen=
erates the best possible code. It has one major drawback: code duplication.=
</span><br></div><div><span style=3D"font-size: 13px;">You have to write <b=
>n^2 </b>constructors for <b>all possible combinations of const& and &a=
mp;&</b>.</span></div><div><div class=3D"prettyprint" style=3D"border: =
1px solid rgb(187, 187, 187); background-color: rgb(250, 250, 250); word-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Example</span><font color=3D=
"#666600"><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"><br> std</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">string</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> s1</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> s2</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span></font><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Example</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
ing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mS1</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&&</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> mS2</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> s1</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">mS1<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)},</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> s2</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">move</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">mS2</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </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><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> <br> </span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Example</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">string</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> mS1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&&</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> mS2</span><span style=3D"co=
lor: #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: #0=
00;" class=3D"styled-by-prettify"> s1</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">mS1</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">},</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> s2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><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">move</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">mS2</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> <br> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Example</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&&</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> mS1</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: #008;=
" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">string</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> mS2</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: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> s1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>mS1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)},</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> s2</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">mS2</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: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </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> </span><span style=3D"color: #606;" class=3D"styled-by-pret=
tify">Example</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">const<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> mS1</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">s=
tring</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mS2</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> s1</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">mS1</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">},</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> s2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">mS2</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;" 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"> <br></span><font color=3D"#666600"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span></font></div></code></div></div><div><s=
pan style=3D"font-size: 13px;"><br></span></div><div><span style=3D"font-si=
ze: 13px;"><br></span></div><div><span style=3D"font-size: 13px;"><br></spa=
n></div><div><font size=3D"6">Proposal: add <b>std::sink<T></b>, whic=
h automatically performs the best possible action, depending on whether T i=
s a const& or an &&</font></div><div><font size=3D"2"><br></fon=
t></div><div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb=
(187, 187, 187); background-color: rgb(250, 250, 250); word-wrap: break-wor=
d;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Example</span><font color=3D"#666600"><sp=
an 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"><br> std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> s1</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> s2</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span></font><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Example</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">st=
d</span><font color=3D"#666600"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">sink</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><</span></font><span style=3D"color: #000;" class=3D"styled-by-prettify=
">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> mS1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">sink</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
ing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> mS2</span><s=
pan 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"> s1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">mS1</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">},</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
s2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">mS2</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: #660;" class=3D"styl=
ed-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> <br></span><font color=3D"#666600"><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">};</span></font></div></code></div></div></div><d=
iv><br></div><div>It should behave exactly <b>as if</b> four construct=
ors (n^2) were written, like in the<b> Approach 2</b> example.</div><div><b=
>std::sink<T> </b>would allow the developer to not call any unnecessa=
ry constructors and to not write n^2 constructors/functions. <b>No performa=
nce trade-off, no code duplication.</b></div><div><br></div><div>Thoug=
hts?</div></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_199_28896140.1378820528515--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Tue, 10 Sep 2013 11:01:58 -0700
Raw View
--047d7b5d452c753d9704e60b4f69
Content-Type: text/plain; charset=ISO-8859-1
Again, my concern is that I don't think this is implementable. In
particular, your proposed syntax requires that sink change its type, which
is a compile time only construct, at run time. You would probably need to
define some new feature in the core language to support this, and that's
going to be the sticking point.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Tue, Sep 10, 2013 at 6:42 AM, <vittorio.romeo.vee@gmail.com> wrote:
> Inspired by my own StackOverflow question.<http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments>
>
> Problem: passing sink arguments efficiently requires either a lot of code
> duplication or performance trade-offs.
>
> Thanks to move semantics in C++11, we can now efficiently move large
> objects.
> In many occasions we require to pass a *sink argument, *which is an
> argument that will get stored somewhere, or it will be used then
> immediately discarded.
>
> Here's the most common example: initializing a class instance with an
> std::string.
>
> *
> *
> *
> *
> *Approach 1: pass by value + std::move*
> struct Example {
> std::string s;
> Example(std::string mS) : s{std::move(mS)} { }
> };
> If *mS *is a temporary: the value is initialized from the temporary by
> moving, and then you yourself move from the argument, thus no copy is made.
> *Result: **1 move*
>
> If *mS* is an lvalue: you copy it in the argument and then move from it,
> thus a single copy + move is made.
> *Result: **1 copy + 1 move*
> *
> *
> *
> *
> *
> *
> *Approa**ch 2: have two constructors (one by const&, one by &&)*
> struct Example {
> std::string s;
> Example(std::string&& mS) : s{std::move(mS)} { } // ctor 1
> Example(const std::string& mS) : s{mS} { } // ctor 2
> };
> If *mS *is a temporary: ctor 1 is called. No copy is made. Only the move
> constructor for mS is called.
> *Result: **1 move*
>
> If *mS* is an lvalue: you copy it in the argument, thus a single copy is
> made.
> *Result: **1 copy*
>
> *Additional benefit*:
>
>> No additional code is generated on the caller's side! The calling of the
>> copy- or move-constructor (which might be inlined or not) can now live in
>> the implementation of the called function (here: Test::Test) and therefore
>> only a single copy of that code is required. If you use by-value parameter
>> passing, the caller is responsible for producing the object that is passed
>> to the function.
>
>
>
>
> As you can see, *Approach 2 *has the most efficient results and generates
> the best possible code. It has one major drawback: code duplication.
> You have to write *n^2 *constructors for *all possible combinations of
> const& and &&*.
> struct Example {
> std::string s1, s2;
> Example(std::string&& mS1, std::string&& mS2) : s1{std::move
> (mS1)}, s2{std::move(mS2)} { }
> Example(const std::string& mS1, std::string&& mS2) : s1{mS1}, s2{
> std::move(mS2)} { }
> Example(std::string&& mS1, const std::string& mS2) : s1{std::move
> (mS1)}, s2{mS2} { }
> Example(const std::string& mS1, const std::string& mS2) : s1{mS1}, s2{
> mS2} { }
> };
>
>
>
> Proposal: add *std::sink<T>*, which automatically performs the best
> possible action, depending on whether T is a const& or an &&
>
> struct Example {
> std::string s1, s2;
> Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{
> mS1}, s2{mS2} { }
> };
>
> It should behave exactly *as if* four constructors (n^2) were written,
> like in the* Approach 2* example.
> *std::sink<T> *would allow the developer to not call any unnecessary
> constructors and to not write n^2 constructors/functions. *No
> performance trade-off, no code duplication.*
>
> Thoughts?
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b5d452c753d9704e60b4f69
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Again, my concern is that I don't think this is implem=
entable. In particular, your proposed syntax requires that sink change its =
type, which is a compile time only construct, at run time. You would probab=
ly need to define some new feature in the core language to support this, an=
d that's going to be the sticking point.</div>
<div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><div>Bil=
ly O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" targe=
t=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"http:/=
/stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://stacko=
verflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Tue, Sep 10, 2013 at 6:42 AM, <span =
dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo.vee@gmail.com" target=3D"_=
blank">vittorio.romeo.vee@gmail.com</a>></span> wrote:<br><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">
<div dir=3D"ltr"><a href=3D"http://stackoverflow.com/questions/18673658/sho=
uld-i-always-move-on-sink-constructor-or-setter-arguments" target=3D"_blank=
">Inspired by my own StackOverflow question.</a><div><br></div><div><font s=
ize=3D"6">Problem: passing sink arguments efficiently requires either a lot=
of code duplication or performance=A0trade-offs.</font></div>
<div><br></div><div>Thanks to move semantics in C++11, we can now efficient=
ly move large objects.=A0</div><div>In many occasions we require to pass a =
<i>sink argument, </i>which is an argument that will get stored somewhere, =
or it will be used then immediately discarded.</div>
<div><br></div><div>Here's the most common example: initializing a clas=
s instance with an std::string.</div><div><br></div><div><b><br></b></div><=
div><b><br></b></div><div><b>Approach 1: pass by value + std::move</b></div=
>
<div><div style=3D"border:1px solid rgb(187,187,187);background-color:rgb(2=
50,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">struct</span><sp=
an> </span><span style=3D"color:rgb(102,0,102)">Example</span><font color=
=3D"#666600"><span> </span><span style=3D"color:rgb(102,102,0)">{</span><sp=
an><br>
=A0 =A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(0,0,136)">string</span><span> s</span><span style=3D"color:rg=
b(102,102,0)">;</span><span><br>=A0 =A0 </span><span style=3D"color:rgb(102=
,0,102)">Example</span><span style=3D"color:rgb(102,102,0)">(</span><span>s=
td</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color=
:rgb(0,0,136)">string</span><span> mS</span><span style=3D"color:rgb(102,10=
2,0)">)</span><span> </span><span style=3D"color:rgb(102,102,0)">:</span><s=
pan> s</span><span style=3D"color:rgb(102,102,0)">{</span><span>std</span><=
span style=3D"color:rgb(102,102,0)">::</span><span>move</span><span style=
=3D"color:rgb(102,102,0)">(</span><span>mS</span><span style=3D"color:rgb(1=
02,102,0)">)}</span><span> </span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span> </span><span style=3D"color:rgb(102,102,0)">}</span><span><br>
</span></font><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">=
};</span></font></div></code></div></div><div>If <b>mS </b>is a temporary: =
the value is initialized from the temporary by moving, and then you yoursel=
f move from the argument, thus no copy is made.</div>
<div><i>Result: </i><b>1 move</b></div><div><br></div><div>If <b>mS</b> is =
an lvalue:=A0you copy it in the argument and then move from it, thus a sing=
le copy + move is made.</div><div><i>Result: </i><b>1 copy + 1 move</b></di=
v>
<div><b><br></b></div><div><b><br></b></div><div><b><br></b></div><div><b>A=
pproa</b><b>ch 2: have two constructors (one by const&, one by &&am=
p;)</b></div><div><div style=3D"border:1px solid rgb(187,187,187);backgroun=
d-color:rgb(250,250,250)">
<code><div><span style=3D"color:rgb(0,0,136)">struct</span><span> </span><s=
pan style=3D"color:rgb(102,0,102)">Example</span><font color=3D"#666600"><s=
pan> </span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=A0 =A0 =
std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"colo=
r:rgb(0,0,136)">string</span><span> s</span><span style=3D"color:rgb(102,10=
2,0)">;</span><span><br>
</span></font><span>=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Exa=
mple</span><span style=3D"color:rgb(102,102,0)">(</span><span>std</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136=
)">string</span><span style=3D"color:rgb(102,102,0)">&&</span><span=
> mS</span><span style=3D"color:rgb(102,102,0)">)</span><span> </span><span=
style=3D"color:rgb(102,102,0)">:</span><span> s</span><span style=3D"color=
:rgb(102,102,0)">{</span><span>std</span><span style=3D"color:rgb(102,102,0=
)">::</span><span>move</span><span style=3D"color:rgb(102,102,0)">(</span><=
span>mS</span><span style=3D"color:rgb(102,102,0)">)}</span><span> </span><=
span style=3D"color:rgb(102,102,0)">{</span><span> </span><span style=3D"co=
lor:rgb(102,102,0)">}</span><span> </span><span style=3D"color:rgb(136,0,0)=
">// ctor 1</span><font color=3D"#666600"><span><br>
=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Example</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">cons=
t</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><spa=
n style=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,10=
2,0)">&</span><span> mS</span><span style=3D"color:rgb(102,102,0)">)</s=
pan><span> </span><span style=3D"color:rgb(102,102,0)">:</span><span> s</sp=
an><span style=3D"color:rgb(102,102,0)">{</span><span>mS</span><span style=
=3D"color:rgb(102,102,0)">}</span><span> </span><span style=3D"color:rgb(10=
2,102,0)">{</span><span> </span><span style=3D"color:rgb(102,102,0)">}</spa=
n><span> =A0 =A0 =A0 </span><span style=3D"color:rgb(136,0,0)">// ctor 2</s=
pan></font><font color=3D"#666600"><span><br>
</span><span style=3D"color:rgb(102,102,0)">};</span></font></div></code></=
div><div>If=A0<b>mS=A0</b>is a temporary:=A0ctor 1 is called. No copy is ma=
de. Only the move constructor for mS is called.</div><div><i>Result:=A0</i>=
<b>1 move</b></div>
<div><br></div><div>If=A0<b>mS</b>=A0is an lvalue:=A0you copy it in the arg=
ument, thus a single copy is made.</div><div><i>Result:=A0</i><b>1 copy</b>=
</div><br></div><div><i>Additional benefit</i>:</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-=
color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
No additional code is generated on the caller's side! The calling of th=
e copy- or move-constructor (which might be inlined or not) can now live in=
the implementation of the called function (here: Test::Test) and therefore=
only a single copy of that code is required. If you use by-value parameter=
passing, the caller is responsible for producing the object that is passed=
to the function.</blockquote>
<div><br></div><div><span style=3D"font-size:13px"><br></span></div><div><s=
pan style=3D"font-size:13px"><br></span></div><div><span style=3D"font-size=
:13px">As you can see, <b>Approach 2 </b>has the most efficient results and=
generates the best possible code. It has one major drawback: code duplicat=
ion.</span><br>
</div><div><span style=3D"font-size:13px">You have to write <b>n^2 </b>cons=
tructors for <b>all possible combinations of const& and &&</b>.=
</span></div><div><div style=3D"border:1px solid rgb(187,187,187);backgroun=
d-color:rgb(250,250,250)">
<code><div><span style=3D"color:rgb(0,0,136)">struct</span><span> </span><s=
pan style=3D"color:rgb(102,0,102)">Example</span><font color=3D"#666600"><s=
pan> </span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=A0 =A0 =
std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"colo=
r:rgb(0,0,136)">string</span><span> s1</span><span style=3D"color:rgb(102,1=
02,0)">,</span><span> s2</span><span style=3D"color:rgb(102,102,0)">;</span=
><span><br>
</span></font><span>=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Exa=
mple</span><span style=3D"color:rgb(102,102,0)">(</span><span>std</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136=
)">string</span><span style=3D"color:rgb(102,102,0)">&&</span><span=
> mS1</span><span style=3D"color:rgb(102,102,0)">,</span><span> =A0 =A0 =A0=
std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"colo=
r:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)">&&=
;</span><span> mS2</span><span style=3D"color:rgb(102,102,0)">)</span><span=
> =A0 =A0 =A0</span><span style=3D"color:rgb(102,102,0)">:</span><span> s1<=
/span><span style=3D"color:rgb(102,102,0)">{</span><span>std</span><span st=
yle=3D"color:rgb(102,102,0)">::</span><span>move</span><span style=3D"color=
:rgb(102,102,0)">(</span><span>mS1</span><span style=3D"color:rgb(102,102,0=
)">)},</span><span> s2</span><span style=3D"color:rgb(102,102,0)">{</span><=
span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>move</sp=
an><span style=3D"color:rgb(102,102,0)">(</span><span>mS2</span><span style=
=3D"color:rgb(102,102,0)">)}</span><span> </span><span style=3D"color:rgb(1=
02,102,0)">{</span><span> </span><span style=3D"color:rgb(102,102,0)">}</sp=
an><span> <br>
=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Example</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">cons=
t</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><spa=
n style=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,10=
2,0)">&</span><span> mS1</span><span style=3D"color:rgb(102,102,0)">,</=
span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><span s=
tyle=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0=
)">&&</span><span> mS2</span><span style=3D"color:rgb(102,102,0)">)=
</span><span> =A0 =A0 =A0</span><span style=3D"color:rgb(102,102,0)">:</spa=
n><span> s1</span><span style=3D"color:rgb(102,102,0)">{</span><span>mS1</s=
pan><span style=3D"color:rgb(102,102,0)">},</span><span> s2</span><span sty=
le=3D"color:rgb(102,102,0)">{</span><span>std</span><span style=3D"color:rg=
b(102,102,0)">::</span><span>move</span><span style=3D"color:rgb(102,102,0)=
">(</span><span>mS2</span><span style=3D"color:rgb(102,102,0)">)}</span><sp=
an> </span><span style=3D"color:rgb(102,102,0)">{</span><span> </span><span=
style=3D"color:rgb(102,102,0)">}</span><span> <br>
=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Example</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span>std</span><span style=3D"color:rg=
b(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><spa=
n style=3D"color:rgb(102,102,0)">&&</span><span> mS1</span><span st=
yle=3D"color:rgb(102,102,0)">,</span><span> =A0 =A0 =A0</span><span style=
=3D"color:rgb(0,0,136)">const</span><span> std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><sp=
an style=3D"color:rgb(102,102,0)">&</span><span> mS2</span><span style=
=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"color:rgb(10=
2,102,0)">:</span><span> s1</span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>mov=
e</span><span style=3D"color:rgb(102,102,0)">(</span><span>mS1</span><span =
style=3D"color:rgb(102,102,0)">)},</span><span> s2</span><span style=3D"col=
or:rgb(102,102,0)">{</span><span>mS2</span><span style=3D"color:rgb(102,102=
,0)">}</span><span> </span><span style=3D"color:rgb(102,102,0)">{</span><sp=
an> </span><span style=3D"color:rgb(102,102,0)">}</span><span> <br>
=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Example</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">cons=
t</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><spa=
n style=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,10=
2,0)">&</span><span> mS1</span><span style=3D"color:rgb(102,102,0)">,</=
span><span> </span><span style=3D"color:rgb(0,0,136)">const</span><span> st=
d</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:=
rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)">&</span=
><span> mS2</span><span style=3D"color:rgb(102,102,0)">)</span><span> </spa=
n><span style=3D"color:rgb(102,102,0)">:</span><span> s1</span><span style=
=3D"color:rgb(102,102,0)">{</span><span>mS1</span><span style=3D"color:rgb(=
102,102,0)">},</span><span> s2</span><span style=3D"color:rgb(102,102,0)">{=
</span><span>mS2</span><span style=3D"color:rgb(102,102,0)">}</span><span> =
</span><span style=3D"color:rgb(102,102,0)">{</span><span> </span><span sty=
le=3D"color:rgb(102,102,0)">}</span><span> <br>
</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">};</spa=
n></font></div></code></div></div><div><span style=3D"font-size:13px"><br><=
/span></div><div><span style=3D"font-size:13px"><br></span></div><div><span=
style=3D"font-size:13px"><br>
</span></div><div><font size=3D"6">Proposal: add <b>std::sink<T></b>,=
which automatically performs the best possible action, depending on whethe=
r T is a const& or an &&</font></div><div><font><br></font></di=
v>
<div><div><div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">struct</spa=
n><span> </span><span style=3D"color:rgb(102,0,102)">Example</span><font co=
lor=3D"#666600"><span> </span><span style=3D"color:rgb(102,102,0)">{</span>=
<span><br>
=A0 =A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=
=3D"color:rgb(0,0,136)">string</span><span> s1</span><span style=3D"color:r=
gb(102,102,0)">,</span><span> s2</span><span style=3D"color:rgb(102,102,0)"=
>;</span><span><br>
</span></font><span>=A0 =A0 </span><span style=3D"color:rgb(102,0,102)">Exa=
mple</span><span style=3D"color:rgb(102,102,0)">(</span><span>std</span><fo=
nt color=3D"#666600"><span style=3D"color:rgb(102,102,0)">::</span><span>si=
nk</span><span style=3D"color:rgb(102,102,0)"><</span></font><span>std</=
span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb=
(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)">></span><sp=
an> mS1</span><span style=3D"color:rgb(102,102,0)">,</span><span> std</span=
><span style=3D"color:rgb(102,102,0)">::</span><span>sink</span><span style=
=3D"color:rgb(102,102,0)"><</span><span>std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><sp=
an style=3D"color:rgb(102,102,0)">></span><span> mS2</span><span style=
=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"color:rgb(10=
2,102,0)">:</span><span> s1</span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span>mS1</span><span style=3D"color:rgb(102,102,0)">},</span><span> s2=
</span><span style=3D"color:rgb(102,102,0)">{</span><span>mS2</span><span s=
tyle=3D"color:rgb(102,102,0)">}</span><span> </span><span style=3D"color:rg=
b(102,102,0)">{</span><span> </span><span style=3D"color:rgb(102,102,0)">}<=
/span><span> <br>
</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">};</spa=
n></font></div></code></div></div></div><div><br></div><div>It should behav=
e exactly <b>as if</b>=A0four constructors (n^2) were written, like in the<=
b> Approach 2</b> example.</div>
<div><b>std::sink<T> </b>would allow the developer to not call any un=
necessary constructors and to not write n^2 constructors/functions. <b>No p=
erformance=A0trade-off, no code duplication.</b></div><div><br></div><div>
Thoughts?</div></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
=A0<br>
--- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b5d452c753d9704e60b4f69--
.
Author: Vittorio Romeo <vittorio.romeo@outlook.com>
Date: Tue, 10 Sep 2013 21:00:24 +0200
Raw View
--_56d08cee-d473-49b1-9c19-5a37a8dcc763_
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
This is a duplicate thread - I submitted it earlier but for some reason it =
didn't appear until now.Feel free to delete it / merge it with the other on=
e if possible.
I understand your concern, but this feels like a language defect honestly. =
It makes no sense that you're forced to write 2^n constructors to achieve b=
est efficiency.
From: billy.oneal@gmail.com
Date: Tue, 10 Sep 2013 11:01:58 -0700
Subject: Re: [std-proposals] std::sink<T> - always pass sink arguments effi=
ciently
To: std-proposals@isocpp.org
Again, my concern is that I don't think this is implementable. In particula=
r, your proposed syntax requires that sink change its type, which is a comp=
ile time only construct, at run time. You would probably need to define som=
e new feature in the core language to support this, and that's going to be =
the sticking point.
Billy O'Nealhttps://github.com/BillyONeal/http://stackoverflow.com/users/82=
320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Tue, Sep 10, 2013 at 6:42 AM, <vittorio.romeo.vee@gmail.com> wrote:
Inspired by my own StackOverflow question.
Problem: passing sink arguments efficiently requires either a lot of code d=
uplication or performance trade-offs.
Thanks to move semantics in C++11, we can now efficiently move large object=
s. In many occasions we require to pass a sink argument, which is an argume=
nt that will get stored somewhere, or it will be used then immediately disc=
arded.
Here's the most common example: initializing a class instance with an std::=
string.
Approach 1: pass by value + std::move
struct Example {
std::string s;
Example(std::string mS) : s{std::move(mS)} { }
};If mS is a temporary: the value is initialized from the temporary by movi=
ng, and then you yourself move from the argument, thus no copy is made.
Result: 1 move
If mS is an lvalue: you copy it in the argument and then move from it, thus=
a single copy + move is made.Result: 1 copy + 1 move
Approach 2: have two constructors (one by const&, one by &&)
struct Example {
std::string s;
Example(std::string&& mS) : s{std::move(mS)} { } // ctor 1
Example(const std::string& mS) : s{mS} { } // ctor 2
};If mS is a temporary: ctor 1 is called. No copy is made. Only the move co=
nstructor for mS is called.Result: 1 move
If mS is an lvalue: you copy it in the argument, thus a single copy is made=
..Result: 1 copy
Additional benefit:
No additional code is generated on the caller's side! The calling of the co=
py- or move-constructor (which might be inlined or not) can now live in the=
implementation of the called function (here: Test::Test) and therefore onl=
y a single copy of that code is required. If you use by-value parameter pas=
sing, the caller is responsible for producing the object that is passed to =
the function.
As you can see, Approach 2 has the most efficient results and generates the=
best possible code. It has one major drawback: code duplication.
You have to write n^2 constructors for all possible combinations of const& =
and &&.
struct Example {
std::string s1, s2;
Example(std::string&& mS1, std::string&& mS2) : s1{std::move(=
mS1)}, s2{std::move(mS2)} { }=20
Example(const std::string& mS1, std::string&& mS2) : s1{mS1}, s2{s=
td::move(mS2)} { }=20
Example(std::string&& mS1, const std::string& mS2) : s1{std::move(=
mS1)}, s2{mS2} { }=20
Example(const std::string& mS1, const std::string& mS2) : s1{mS1}, s2{m=
S2} { }=20
};
Proposal: add std::sink<T>, which automatically performs the best possible =
action, depending on whether T is a const& or an &&
struct Example {
std::string s1, s2;
Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{mS=
1}, s2{mS2} { }=20
};
It should behave exactly as if four constructors (n^2) were written, like i=
n the Approach 2 example.
std::sink<T> would allow the developer to not call any unnecessary construc=
tors and to not write n^2 constructors/functions. No performance trade-off,=
no code duplication.
Thoughts?
--=20
=20
---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--=20
=20
---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
=20
--=20
---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--_56d08cee-d473-49b1-9c19-5a37a8dcc763_
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<style><!--
..hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class=3D'hmmessage'><div dir=3D'ltr'>This is a duplicate thread - I s=
ubmitted it earlier but for some reason it didn't appear until now.<div>Fee=
l free to delete it / merge it with the other one if possible.</div><div><b=
r>I understand your concern, but this feels like a language defect honestly=
.. It makes no sense that you're forced to write 2^n constructors to achieve=
best efficiency.<br><br><div><hr id=3D"stopSpelling">From: billy.oneal@gma=
il.com<br>Date: Tue, 10 Sep 2013 11:01:58 -0700<br>Subject: Re: [std-propos=
als] std::sink<T> - always pass sink arguments efficiently<br>To: std=
-proposals@isocpp.org<br><br><div dir=3D"ltr">Again, my concern is that I d=
on't think this is implementable. In particular, your proposed syntax requi=
res that sink change its type, which is a compile time only construct, at r=
un time. You would probably need to define some new feature in the core lan=
guage to support this, and that's going to be the sticking point.</div>
<div class=3D"ecxgmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><div>=
Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" target=
=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"http://=
stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://stackov=
erflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"ecxgmail_quote">On Tue, Sep 10, 2013 at 6:42 AM, <sp=
an dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo.vee@gmail.com" target=
=3D"_blank">vittorio.romeo.vee@gmail.com</a>></span> wrote:<br><blockquo=
te class=3D"ecxgmail_quote" style=3D"border-left:1px #ccc solid;padding-lef=
t:1ex;">
<div dir=3D"ltr"><a href=3D"http://stackoverflow.com/questions/18673658/sho=
uld-i-always-move-on-sink-constructor-or-setter-arguments" target=3D"_blank=
">Inspired by my own StackOverflow question.</a><div><br></div><div><font s=
ize=3D"6">Problem: passing sink arguments efficiently requires either a lot=
of code duplication or performance trade-offs.</font></div>
<div><br></div><div>Thanks to move semantics in C++11, we can now efficient=
ly move large objects. </div><div>In many occasions we require to pass=
a <i>sink argument, </i>which is an argument that will get stored somewher=
e, or it will be used then immediately discarded.</div>
<div><br></div><div>Here's the most common example: initializing a class in=
stance with an std::string.</div><div><br></div><div><b><br></b></div><div>=
<b><br></b></div><div><b>Approach 1: pass by value + std::move</b></div>
<div><div style=3D"border:1px solid rgb(187,187,187);background-color:rgb(2=
50,250,250);"><code><div><span style=3D"color:rgb(0,0,136);">struct</span><=
span> </span><span style=3D"color:rgb(102,0,102);">Example</span><font colo=
r=3D"#666600"><span> </span><span style=3D"color:rgb(102,102,0);">{</span><=
span><br>
std</span><span style=3D"color:rgb(102,102,0);">::</span><spa=
n style=3D"color:rgb(0,0,136);">string</span><span> s</span><span style=3D"=
color:rgb(102,102,0);">;</span><span><br> </span><span style=
=3D"color:rgb(102,0,102);">Example</span><span style=3D"color:rgb(102,102,0=
);">(</span><span>std</span><span style=3D"color:rgb(102,102,0);">::</span>=
<span style=3D"color:rgb(0,0,136);">string</span><span> mS</span><span styl=
e=3D"color:rgb(102,102,0);">)</span><span> </span><span style=3D"color:rgb(=
102,102,0);">:</span><span> s</span><span style=3D"color:rgb(102,102,0);">{=
</span><span>std</span><span style=3D"color:rgb(102,102,0);">::</span><span=
>move</span><span style=3D"color:rgb(102,102,0);">(</span><span>mS</span><s=
pan style=3D"color:rgb(102,102,0);">)}</span><span> </span><span style=3D"c=
olor:rgb(102,102,0);">{</span><span> </span><span style=3D"color:rgb(102,10=
2,0);">}</span><span><br>
</span></font><font color=3D"#666600"><span style=3D"color:rgb(102,102,0);"=
>};</span></font></div></code></div></div><div>If <b>mS </b>is a temporary:=
the value is initialized from the temporary by moving, and then you yourse=
lf move from the argument, thus no copy is made.</div>
<div><i>Result: </i><b>1 move</b></div><div><br></div><div>If <b>mS</b> is =
an lvalue: you copy it in the argument and then move from it, thus a s=
ingle copy + move is made.</div><div><i>Result: </i><b>1 copy + 1 move</b><=
/div>
<div><b><br></b></div><div><b><br></b></div><div><b><br></b></div><div><b>A=
pproa</b><b>ch 2: have two constructors (one by const&, one by &&am=
p;)</b></div><div><div style=3D"border:1px solid rgb(187,187,187);backgroun=
d-color:rgb(250,250,250);">
<code><div><span style=3D"color:rgb(0,0,136);">struct</span><span> </span><=
span style=3D"color:rgb(102,0,102);">Example</span><font color=3D"#666600">=
<span> </span><span style=3D"color:rgb(102,102,0);">{</span><span><br> =
; std</span><span style=3D"color:rgb(102,102,0);">::</span><span sty=
le=3D"color:rgb(0,0,136);">string</span><span> s</span><span style=3D"color=
:rgb(102,102,0);">;</span><span><br>
</span></font><span> </span><span style=3D"color:rgb(102,0,102=
);">Example</span><span style=3D"color:rgb(102,102,0);">(</span><span>std</=
span><span style=3D"color:rgb(102,102,0);">::</span><span style=3D"color:rg=
b(0,0,136);">string</span><span style=3D"color:rgb(102,102,0);">&&<=
/span><span> mS</span><span style=3D"color:rgb(102,102,0);">)</span><span> =
</span><span style=3D"color:rgb(102,102,0);">:</span><span> s</span><span s=
tyle=3D"color:rgb(102,102,0);">{</span><span>std</span><span style=3D"color=
:rgb(102,102,0);">::</span><span>move</span><span style=3D"color:rgb(102,10=
2,0);">(</span><span>mS</span><span style=3D"color:rgb(102,102,0);">)}</spa=
n><span> </span><span style=3D"color:rgb(102,102,0);">{</span><span> </span=
><span style=3D"color:rgb(102,102,0);">}</span><span> </span><span style=3D=
"color:rgb(136,0,0);">// ctor 1</span><font color=3D"#666600"><span><br>
</span><span style=3D"color:rgb(102,0,102);">Example</span><s=
pan style=3D"color:rgb(102,102,0);">(</span><span style=3D"color:rgb(0,0,13=
6);">const</span><span> std</span><span style=3D"color:rgb(102,102,0);">::<=
/span><span style=3D"color:rgb(0,0,136);">string</span><span style=3D"color=
:rgb(102,102,0);">&</span><span> mS</span><span style=3D"color:rgb(102,=
102,0);">)</span><span> </span><span style=3D"color:rgb(102,102,0);">:</spa=
n><span> s</span><span style=3D"color:rgb(102,102,0);">{</span><span>mS</sp=
an><span style=3D"color:rgb(102,102,0);">}</span><span> </span><span style=
=3D"color:rgb(102,102,0);">{</span><span> </span><span style=3D"color:rgb(1=
02,102,0);">}</span><span> </span><span style=3D"color=
:rgb(136,0,0);">// ctor 2</span></font><font color=3D"#666600"><span><br>
</span><span style=3D"color:rgb(102,102,0);">};</span></font></div></code><=
/div><div>If <b>mS </b>is a temporary: ctor 1 is called. No =
copy is made. Only the move constructor for mS is called.</div><div><i>Resu=
lt: </i><b>1 move</b></div>
<div><br></div><div>If <b>mS</b> is an lvalue: you copy it i=
n the argument, thus a single copy is made.</div><div><i>Result: </i><=
b>1 copy</b></div><br></div><div><i>Additional benefit</i>:</div><blockquot=
e class=3D"ecxgmail_quote" style=3D"padding-left:1ex;border-left-color:rgb(=
204,204,204);border-left-width:1px;border-left-style:solid;">
No additional code is generated on the caller's side! The calling of the co=
py- or move-constructor (which might be inlined or not) can now live in the=
implementation of the called function (here: Test::Test) and therefore onl=
y a single copy of that code is required. If you use by-value parameter pas=
sing, the caller is responsible for producing the object that is passed to =
the function.</blockquote>
<div><br></div><div><span style=3D"font-size:13px;"><br></span></div><div><=
span style=3D"font-size:13px;"><br></span></div><div><span style=3D"font-si=
ze:13px;">As you can see, <b>Approach 2 </b>has the most efficient results =
and generates the best possible code. It has one major drawback: code dupli=
cation.</span><br>
</div><div><span style=3D"font-size:13px;">You have to write <b>n^2 </b>con=
structors for <b>all possible combinations of const& and &&</b>=
..</span></div><div><div style=3D"border:1px solid rgb(187,187,187);backgrou=
nd-color:rgb(250,250,250);">
<code><div><span style=3D"color:rgb(0,0,136);">struct</span><span> </span><=
span style=3D"color:rgb(102,0,102);">Example</span><font color=3D"#666600">=
<span> </span><span style=3D"color:rgb(102,102,0);">{</span><span><br> =
; std</span><span style=3D"color:rgb(102,102,0);">::</span><span sty=
le=3D"color:rgb(0,0,136);">string</span><span> s1</span><span style=3D"colo=
r:rgb(102,102,0);">,</span><span> s2</span><span style=3D"color:rgb(102,102=
,0);">;</span><span><br>
</span></font><span> </span><span style=3D"color:rgb(102,0,102=
);">Example</span><span style=3D"color:rgb(102,102,0);">(</span><span>std</=
span><span style=3D"color:rgb(102,102,0);">::</span><span style=3D"color:rg=
b(0,0,136);">string</span><span style=3D"color:rgb(102,102,0);">&&<=
/span><span> mS1</span><span style=3D"color:rgb(102,102,0);">,</span><span>=
std</span><span style=3D"color:rgb(102,102,0);">::</sp=
an><span style=3D"color:rgb(0,0,136);">string</span><span style=3D"color:rg=
b(102,102,0);">&&</span><span> mS2</span><span style=3D"color:rgb(1=
02,102,0);">)</span><span> </span><span style=3D"color:=
rgb(102,102,0);">:</span><span> s1</span><span style=3D"color:rgb(102,102,0=
);">{</span><span>std</span><span style=3D"color:rgb(102,102,0);">::</span>=
<span>move</span><span style=3D"color:rgb(102,102,0);">(</span><span>mS1</s=
pan><span style=3D"color:rgb(102,102,0);">)},</span><span> s2</span><span s=
tyle=3D"color:rgb(102,102,0);">{</span><span>std</span><span style=3D"color=
:rgb(102,102,0);">::</span><span>move</span><span style=3D"color:rgb(102,10=
2,0);">(</span><span>mS2</span><span style=3D"color:rgb(102,102,0);">)}</sp=
an><span> </span><span style=3D"color:rgb(102,102,0);">{</span><span> </spa=
n><span style=3D"color:rgb(102,102,0);">}</span><span> <br>
</span><span style=3D"color:rgb(102,0,102);">Example</span><s=
pan style=3D"color:rgb(102,102,0);">(</span><span style=3D"color:rgb(0,0,13=
6);">const</span><span> std</span><span style=3D"color:rgb(102,102,0);">::<=
/span><span style=3D"color:rgb(0,0,136);">string</span><span style=3D"color=
:rgb(102,102,0);">&</span><span> mS1</span><span style=3D"color:rgb(102=
,102,0);">,</span><span> std</span><span style=3D"color:rgb(102,102,0);">::=
</span><span style=3D"color:rgb(0,0,136);">string</span><span style=3D"colo=
r:rgb(102,102,0);">&&</span><span> mS2</span><span style=3D"color:r=
gb(102,102,0);">)</span><span> </span><span style=3D"co=
lor:rgb(102,102,0);">:</span><span> s1</span><span style=3D"color:rgb(102,1=
02,0);">{</span><span>mS1</span><span style=3D"color:rgb(102,102,0);">},</s=
pan><span> s2</span><span style=3D"color:rgb(102,102,0);">{</span><span>std=
</span><span style=3D"color:rgb(102,102,0);">::</span><span>move</span><spa=
n style=3D"color:rgb(102,102,0);">(</span><span>mS2</span><span style=3D"co=
lor:rgb(102,102,0);">)}</span><span> </span><span style=3D"color:rgb(102,10=
2,0);">{</span><span> </span><span style=3D"color:rgb(102,102,0);">}</span>=
<span> <br>
</span><span style=3D"color:rgb(102,0,102);">Example</span><s=
pan style=3D"color:rgb(102,102,0);">(</span><span>std</span><span style=3D"=
color:rgb(102,102,0);">::</span><span style=3D"color:rgb(0,0,136);">string<=
/span><span style=3D"color:rgb(102,102,0);">&&</span><span> mS1</sp=
an><span style=3D"color:rgb(102,102,0);">,</span><span>  =
;</span><span style=3D"color:rgb(0,0,136);">const</span><span> std</span><s=
pan style=3D"color:rgb(102,102,0);">::</span><span style=3D"color:rgb(0,0,1=
36);">string</span><span style=3D"color:rgb(102,102,0);">&</span><span>=
mS2</span><span style=3D"color:rgb(102,102,0);">)</span><span> </span><spa=
n style=3D"color:rgb(102,102,0);">:</span><span> s1</span><span style=3D"co=
lor:rgb(102,102,0);">{</span><span>std</span><span style=3D"color:rgb(102,1=
02,0);">::</span><span>move</span><span style=3D"color:rgb(102,102,0);">(</=
span><span>mS1</span><span style=3D"color:rgb(102,102,0);">)},</span><span>=
s2</span><span style=3D"color:rgb(102,102,0);">{</span><span>mS2</span><sp=
an style=3D"color:rgb(102,102,0);">}</span><span> </span><span style=3D"col=
or:rgb(102,102,0);">{</span><span> </span><span style=3D"color:rgb(102,102,=
0);">}</span><span> <br>
</span><span style=3D"color:rgb(102,0,102);">Example</span><s=
pan style=3D"color:rgb(102,102,0);">(</span><span style=3D"color:rgb(0,0,13=
6);">const</span><span> std</span><span style=3D"color:rgb(102,102,0);">::<=
/span><span style=3D"color:rgb(0,0,136);">string</span><span style=3D"color=
:rgb(102,102,0);">&</span><span> mS1</span><span style=3D"color:rgb(102=
,102,0);">,</span><span> </span><span style=3D"color:rgb(0,0,136);">const</=
span><span> std</span><span style=3D"color:rgb(102,102,0);">::</span><span =
style=3D"color:rgb(0,0,136);">string</span><span style=3D"color:rgb(102,102=
,0);">&</span><span> mS2</span><span style=3D"color:rgb(102,102,0);">)<=
/span><span> </span><span style=3D"color:rgb(102,102,0);">:</span><span> s1=
</span><span style=3D"color:rgb(102,102,0);">{</span><span>mS1</span><span =
style=3D"color:rgb(102,102,0);">},</span><span> s2</span><span style=3D"col=
or:rgb(102,102,0);">{</span><span>mS2</span><span style=3D"color:rgb(102,10=
2,0);">}</span><span> </span><span style=3D"color:rgb(102,102,0);">{</span>=
<span> </span><span style=3D"color:rgb(102,102,0);">}</span><span> <br>
</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0);">};</sp=
an></font></div></code></div></div><div><span style=3D"font-size:13px;"><br=
></span></div><div><span style=3D"font-size:13px;"><br></span></div><div><s=
pan style=3D"font-size:13px;"><br>
</span></div><div><font size=3D"6">Proposal: add <b>std::sink<T></b>,=
which automatically performs the best possible action, depending on whethe=
r T is a const& or an &&</font></div><div><br></div>
<div><div><div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250);"><code><div><span style=3D"color:rgb(0,0,136);">struct</s=
pan><span> </span><span style=3D"color:rgb(102,0,102);">Example</span><font=
color=3D"#666600"><span> </span><span style=3D"color:rgb(102,102,0);">{</s=
pan><span><br>
std</span><span style=3D"color:rgb(102,102,0);">::</span><spa=
n style=3D"color:rgb(0,0,136);">string</span><span> s1</span><span style=3D=
"color:rgb(102,102,0);">,</span><span> s2</span><span style=3D"color:rgb(10=
2,102,0);">;</span><span><br>
</span></font><span> </span><span style=3D"color:rgb(102,0,102=
);">Example</span><span style=3D"color:rgb(102,102,0);">(</span><span>std</=
span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0);">::</span=
><span>sink</span><span style=3D"color:rgb(102,102,0);"><</span></font><=
span>std</span><span style=3D"color:rgb(102,102,0);">::</span><span style=
=3D"color:rgb(0,0,136);">string</span><span style=3D"color:rgb(102,102,0);"=
>></span><span> mS1</span><span style=3D"color:rgb(102,102,0);">,</span>=
<span> std</span><span style=3D"color:rgb(102,102,0);">::</span><span>sink<=
/span><span style=3D"color:rgb(102,102,0);"><</span><span>std</span><spa=
n style=3D"color:rgb(102,102,0);">::</span><span style=3D"color:rgb(0,0,136=
);">string</span><span style=3D"color:rgb(102,102,0);">></span><span> mS=
2</span><span style=3D"color:rgb(102,102,0);">)</span><span> </span><span s=
tyle=3D"color:rgb(102,102,0);">:</span><span> s1</span><span style=3D"color=
:rgb(102,102,0);">{</span><span>mS1</span><span style=3D"color:rgb(102,102,=
0);">},</span><span> s2</span><span style=3D"color:rgb(102,102,0);">{</span=
><span>mS2</span><span style=3D"color:rgb(102,102,0);">}</span><span> </spa=
n><span style=3D"color:rgb(102,102,0);">{</span><span> </span><span style=
=3D"color:rgb(102,102,0);">}</span><span> <br>
</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0);">};</sp=
an></font></div></code></div></div></div><div><br></div><div>It should beha=
ve exactly <b>as if</b> four constructors (n^2) were written, like in =
the<b> Approach 2</b> example.</div>
<div><b>std::sink<T> </b>would allow the developer to not call any un=
necessary constructors and to not write n^2 constructors/functions. <b>No p=
erformance trade-off, no code duplication.</b></div><div><br></div><di=
v>
Thoughts?</div></div><span class=3D"ecxHOEnZb"><font color=3D"#888888">
<BR>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<BR>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br>
To post to this group, send email to std-proposals@isocpp.org.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br></div></div> </div></body>
</html>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--_56d08cee-d473-49b1-9c19-5a37a8dcc763_--
.
Author: Jared Grubb <jared.grubb@gmail.com>
Date: Tue, 10 Sep 2013 14:23:49 -0700 (PDT)
Raw View
------=_Part_2686_7728176.1378848229973
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, September 10, 2013 6:42:08 AM UTC-7, Vittorio Romeo wrote:
>
> Inspired by my own StackOverflow question.<http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments>
>
> Problem: passing sink arguments efficiently requires either a lot of code
> duplication or performance trade-offs.
>
> Thanks to move semantics in C++11, we can now efficiently move large
> objects.
> In many occasions we require to pass a *sink argument, *which is an
> argument that will get stored somewhere, or it will be used then
> immediately discarded.
>
> Here's the most common example: initializing a class instance with an
> std::string.
>
> *
> *
> *
> *
> *Approach 1: pass by value + std::move*
> struct Example {
> std::string s;
> Example(std::string mS) : s{std::move(mS)} { }
> };
> If *mS *is a temporary: the value is initialized from the temporary by
> moving, and then you yourself move from the argument, thus no copy is made.
> *Result: **1 move*
>
> If *mS* is an lvalue: you copy it in the argument and then move from it,
> thus a single copy + move is made.
> *Result: **1 copy + 1 move*
>
At GoingNative last week, someone mentioned that "move elision" will
(probably?) be added to the standard. That means the compiler is allowed to
remove moves in the same way compilers are allowed to remove copies.
I think that would apply to your example, and so the results would just be
"1 move" and "1 copy", respectively. But, ask a guru, since I'm not 100%
certain.
> **
> *
> *
> *Approa**ch 2: have two constructors (one by const&, one by &&)*
> struct Example {
> std::string s;
> Example(std::string&& mS) : s{std::move(mS)} { } // ctor 1
> Example(const std::string& mS) : s{mS} { } // ctor 2
> };
> If *mS *is a temporary: ctor 1 is called. No copy is made. Only the move
> constructor for mS is called.
> *Result: **1 move*
>
> If *mS* is an lvalue: you copy it in the argument, thus a single copy is
> made.
> *Result: **1 copy*
>
> *Additional benefit*:
>
>> No additional code is generated on the caller's side! The calling of the
>> copy- or move-constructor (which might be inlined or not) can now live in
>> the implementation of the called function (here: Test::Test) and therefore
>> only a single copy of that code is required. If you use by-value parameter
>> passing, the caller is responsible for producing the object that is passed
>> to the function.
>
>
>
>
> As you can see, *Approach 2 *has the most efficient results and generates
> the best possible code. It has one major drawback: code duplication.
> You have to write *n^2 *constructors for *all possible combinations of
> const& and &&*.
> struct Example {
> std::string s1, s2;
> Example(std::string&& mS1, std::string&& mS2) : s1{std::move
> (mS1)}, s2{std::move(mS2)} { }
> Example(const std::string& mS1, std::string&& mS2) : s1{mS1}, s2{
> std::move(mS2)} { }
> Example(std::string&& mS1, const std::string& mS2) : s1{std::move
> (mS1)}, s2{mS2} { }
> Example(const std::string& mS1, const std::string& mS2) : s1{mS1}, s2{
> mS2} { }
> };
>
>
>
> Proposal: add *std::sink<T>*, which automatically performs the best
> possible action, depending on whether T is a const& or an &&
>
> struct Example {
> std::string s1, s2;
> Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{
> mS1}, s2{mS2} { }
> };
>
> It should behave exactly *as if* four constructors (n^2) were written,
> like in the* Approach 2* example.
> *std::sink<T> *would allow the developer to not call any unnecessary
> constructors and to not write n^2 constructors/functions. *No
> performance trade-off, no code duplication.*
>
> Thoughts?
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2686_7728176.1378848229973
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, September 10, 2013 6:42:08 AM UTC-7, V=
ittorio Romeo wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><a href=3D"http://stackoverflow.com/questions/18673658/should-i-al=
ways-move-on-sink-constructor-or-setter-arguments" target=3D"_blank">Inspir=
ed by my own StackOverflow question.</a><div><br></div><div><font size=3D"6=
">Problem: passing sink arguments efficiently requires either a lot of code=
duplication or performance trade-offs.</font></div><div><br></div><di=
v>Thanks to move semantics in C++11, we can now efficiently move large obje=
cts. </div><div>In many occasions we require to pass a <i>sink argumen=
t, </i>which is an argument that will get stored somewhere, or it will be u=
sed then immediately discarded.</div><div><br></div><div>Here's the most co=
mmon example: initializing a class instance with an std::string.</div><div>=
<br></div><div><b><br></b></div><div><b><br></b></div><div><b>Approach 1: p=
ass by value + std::move</b></div><div><div style=3D"border:1px solid rgb(1=
87,187,187);background-color:rgb(250,250,250);word-wrap:break-word"><code><=
div><span style=3D"color:#008">struct</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Example</span><font color=3D"#666600"><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br> std</span><span style=3D"color:#660">::</=
span><span style=3D"color:#008">string</span><span style=3D"color:#000"> s<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>&nb=
sp; </span><span style=3D"color:#606">Example</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#008">string</span><span style=3D"col=
or:#000"> mS</span><span style=3D"color:#660">)</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">:</span><span style=3D"color:#000"=
> s</span><span style=3D"color:#660">{</span><span style=3D"color:#000">std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">move<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#000">mS</spa=
n><span style=3D"color:#660">)}</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">}</span><span style=3D"color:#000"><br></span></font><f=
ont color=3D"#666600"><span style=3D"color:#660">};</span></font></div></co=
de></div></div><div>If <b>mS </b>is a temporary: the value is initialized f=
rom the temporary by moving, and then you yourself move from the argument, =
thus no copy is made.</div><div><i>Result: </i><b>1 move</b></div><div><br>=
</div><div>If <b>mS</b> is an lvalue: you copy it in the argument and =
then move from it, thus a single copy + move is made.</div><div><i>Result: =
</i><b>1 copy + 1 move</b></div></div></blockquote><div><br></div><div>At G=
oingNative last week, someone mentioned that "move elision" will (probably?=
) be added to the standard. That means the compiler is allowed to remove mo=
ves in the same way compilers are allowed to remove copies. </div><div=
><br></div><div>I think that would apply to your example, and so the result=
s would just be "1 move" and "1 copy", respectively. But, ask a guru, since=
I'm not 100% certain.</div><div><br></div><div> </div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><b></b></div><div><b><b=
r></b></div><div><b>Approa</b><b>ch 2: have two constructors (one by const&=
amp;, one by &&)</b></div><div><div style=3D"background-color:rgb(2=
50,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><=
div><span style=3D"color:#008">struct</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Example</span><font color=3D"#666600"><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br> std</span><span style=3D"color:#660">::</=
span><span style=3D"color:#008">string</span><span style=3D"color:#000"> s<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></s=
pan></font><span style=3D"color:#000"> </span><span style=3D"c=
olor:#606">Example</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">std</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#008">string</span><span style=3D"color:#660">&&</span><span st=
yle=3D"color:#000"> mS</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D"c=
olor:#000"> s</span><span style=3D"color:#660">{</span><span style=3D"color=
:#000">std</span><span style=3D"color:#660">::</span><span style=3D"color:#=
000">move</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
0">mS</span><span style=3D"color:#660">)}</span><span style=3D"color:#000">=
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">}</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#800">// ctor 1</span><font color=3D"#666600"><span styl=
e=3D"color:#000"><br> </span><span style=3D"color:#606">Exampl=
e</span><span style=3D"color:#660">(</span><span style=3D"color:#008">const=
</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#008">string</span><span style=3D"color:#660">&a=
mp;</span><span style=3D"color:#000"> mS</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">:</spa=
n><span style=3D"color:#000"> s</span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000">mS</span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">}</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#800">// ctor =
2</span></font><font color=3D"#666600"><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">};</span></font></div></code></div><div>If&nbs=
p;<b>mS </b>is a temporary: ctor 1 is called. No copy is made. On=
ly the move constructor for mS is called.</div><div><i>Result: </i><b>=
1 move</b></div><div><br></div><div>If <b>mS</b> is an lvalue:&nb=
sp;you copy it in the argument, thus a single copy is made.</div><div><i>Re=
sult: </i><b>1 copy</b></div><br></div><div><i>Additional benefit</i>:=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex">No additional code is generated on the caller's side=
! The calling of the copy- or move-constructor (which might be inlined or n=
ot) can now live in the implementation of the called function (here: Test::=
Test) and therefore only a single copy of that code is required. If you use=
by-value parameter passing, the caller is responsible for producing the ob=
ject that is passed to the function.</blockquote><div><br></div><div><span =
style=3D"font-size:13px"><br></span></div><div><span style=3D"font-size:13p=
x"><br></span></div><div><span style=3D"font-size:13px">As you can see, <b>=
Approach 2 </b>has the most efficient results and generates the best possib=
le code. It has one major drawback: code duplication.</span><br></div><div>=
<span style=3D"font-size:13px">You have to write <b>n^2 </b>constructors fo=
r <b>all possible combinations of const& and &&</b>.</span></di=
v><div><div style=3D"border:1px solid rgb(187,187,187);background-color:rgb=
(250,250,250);word-wrap:break-word"><code><div><span style=3D"color:#008">s=
truct</span><span style=3D"color:#000"> </span><span style=3D"color:#606">E=
xample</span><font color=3D"#666600"><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>  =
; std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">=
string</span><span style=3D"color:#000"> s1</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> s2</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"><br></span></font><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Example</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#008">string</span><span styl=
e=3D"color:#660">&&</span><span style=3D"color:#000"> mS1</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> &=
nbsp;std</span><span style=3D"color:#660">::</span><span style=3D"color:#00=
8">string</span><span style=3D"color:#660">&&</span><span style=3D"=
color:#000"> mS2</span><span style=3D"color:#660">)</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">:</span><s=
pan style=3D"color:#000"> s1</span><span style=3D"color:#660">{</span><span=
style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">move</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">mS1</span><span style=3D"color:#660">)},</span><span styl=
e=3D"color:#000"> s2</span><span style=3D"color:#660">{</span><span style=
=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">move</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">mS2</span><span style=3D"color:#660">)}</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">}</span><span style=3D"color:=
#000"> <br> </span><span style=3D"color:#606">Example</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">const</span><sp=
an style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#008">string</span><span style=3D"color:#660">&</span>=
<span style=3D"color:#000"> mS1</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><sp=
an style=3D"color:#008">string</span><span style=3D"color:#660">&&<=
/span><span style=3D"color:#000"> mS2</span><span style=3D"color:#660">)</s=
pan><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">:</span><span style=3D"color:#000"> s1</span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000">mS1</span><span style=3D"color:#=
660">},</span><span style=3D"color:#000"> s2</span><span style=3D"color:#66=
0">{</span><span style=3D"color:#000">std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">move</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">mS2</span><span style=3D"color:#660">)}</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">}</span><span=
style=3D"color:#000"> <br> </span><span style=3D"color:#606">=
Example</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">s=
tring</span><span style=3D"color:#660">&&</span><span style=3D"colo=
r:#000"> mS1</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">const</span><s=
pan style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><sp=
an style=3D"color:#008">string</span><span style=3D"color:#660">&</span=
><span style=3D"color:#000"> mS2</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">:</span><span =
style=3D"color:#000"> s1</span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">move</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">mS1</span><span style=3D"color:#660">)},</span><span style=
=3D"color:#000"> s2</span><span style=3D"color:#660">{</span><span style=3D=
"color:#000">mS2</span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">}</span><span style=3D"color:#000">=
<br> </span><span style=3D"color:#606">Example</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">const</span><span sty=
le=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#008">string</span><span style=3D"color:#660">&</span><span =
style=3D"color:#000"> mS1</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#008">const</span><span sty=
le=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#008">string</span><span style=3D"color:#660">&</span><span =
style=3D"color:#000"> mS2</span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> s1</span><span style=3D"color:#660">{</span><span style=3D=
"color:#000">mS1</span><span style=3D"color:#660">},</span><span style=3D"c=
olor:#000"> s2</span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000">mS2</span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000">=
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"> <br>=
</span><font color=3D"#666600"><span style=3D"color:#660">};</span></font><=
/div></code></div></div><div><span style=3D"font-size:13px"><br></span></di=
v><div><span style=3D"font-size:13px"><br></span></div><div><span style=3D"=
font-size:13px"><br></span></div><div><font size=3D"6">Proposal: add <b>std=
::sink<T></b>, which automatically performs the best possible action,=
depending on whether T is a const& or an &&</font></div><div><=
font size=3D"2"><br></font></div><div><div><div style=3D"border:1px solid r=
gb(187,187,187);background-color:rgb(250,250,250);word-wrap:break-word"><co=
de><div><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
</span><span style=3D"color:#606">Example</span><font color=3D"#666600"><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"><br> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#008">string</span><span style=3D"color:#000"=
> s1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> s=
2</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br><=
/span></font><span style=3D"color:#000"> </span><span style=3D=
"color:#606">Example</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">std</span><font color=3D"#666600"><span style=3D"color:#660=
">::</span><span style=3D"color:#000">sink</span><span style=3D"color:#660"=
><</span></font><span style=3D"color:#000">std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#008">string</span><span style=3D"col=
or:#660">></span><span style=3D"color:#000"> mS1</span><span style=3D"co=
lor:#660">,</span><span style=3D"color:#000"> std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#000">sink</span><span style=3D"color=
:#660"><</span><span style=3D"color:#000">std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#008">string</span><span style=3D"colo=
r:#660">></span><span style=3D"color:#000"> mS2</span><span style=3D"col=
or:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">:</span><span style=3D"color:#000"> s1</span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000">mS1</span><span style=3D"color:#660">},=
</span><span style=3D"color:#000"> s2</span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000">mS2</span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">}</span><span sty=
le=3D"color:#000"> <br></span><font color=3D"#666600"><span style=3D"color:=
#660">};</span></font></div></code></div></div></div><div><br></div><div>It=
should behave exactly <b>as if</b> four constructors (n^2) were writt=
en, like in the<b> Approach 2</b> example.</div><div><b>std::sink<T> =
</b>would allow the developer to not call any unnecessary constructors and =
to not write n^2 constructors/functions. <b>No performance trade-off, =
no code duplication.</b></div><div><br></div><div>Thoughts?</div></div></bl=
ockquote></div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2686_7728176.1378848229973--
.
Author: Jonathan Wakely <cxx@kayari.org>
Date: Wed, 11 Sep 2013 06:28:57 -0700 (PDT)
Raw View
------=_Part_262_8176684.1378906137272
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, September 10, 2013 10:23:49 PM UTC+1, Jared Grubb wrote:
>
>
> At GoingNative last week, someone mentioned that "move elision" will
> (probably?) be added to the standard. That means the compiler is allowed to
> remove moves in the same way compilers are allowed to remove copies.
>
>
That's already allowed in C++11.
However, this is a duplicate thread, let's keep replies in the other one so
the discussion doesn't split in two, please.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_262_8176684.1378906137272
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Tuesday, September 10, 2013 10:23:49 PM UTC+1, Jare=
d Grubb wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><br><div>At GoingNative last week, someone mentioned that "move elision" w=
ill (probably?) be added to the standard. That means the compiler is allowe=
d to remove moves in the same way compilers are allowed to remove copies.&n=
bsp;</div><div><br></div></div></blockquote><div><br>That's already allowed=
in C++11.</div><br>However, this is a duplicate thread, let's keep replies=
in the other one so the discussion doesn't split in two, please.</div>
<p></p>
-- <br />
<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_262_8176684.1378906137272--
.