Topic: std::sink<T> to efficiently pass `sink` arguments
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Tue, 10 Sep 2013 08:29:18 -0700 (PDT)
Raw View
------=_Part_235_28579229.1378826958240
Content-Type: text/plain; charset=ISO-8859-1
*Inspired by my own StackOverflow question*: Should I always move on *sink* constructor
or setter arguments?<http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments>
<https://gist.github.com/SuperV1234/6509614#problem-passing-sink-arguments-efficiently-either-requires-performance-trade-offs-or-extensive-code-duplication>Problem:
passing *sink* arguments efficiently either requires performance trade-offs
or extensive code duplication<https://gist.github.com/SuperV1234/6509614#current-possible-approaches>Current
possible approaches <https://gist.github.com/SuperV1234/6509614#approach-1>Approach
1 <https://gist.github.com/SuperV1234/6509614#pass-by-value-and-stdmove>Pass
by value and std::move
struct Example {
std::string s1, s2;
Example(std::string mS1, std::string mS2) : s1{std::move(mS1)}, s2{std::move(mS2)} { } };
- *Passed argument is a temporary*: it is moved without copies. *Result:
1 move.
**Passed argument is an lvalue*: it is copied, then moved. *Result: 1
copy + 1 move.*
-
*Pros*: no code duplication.
*Cons*: unnecessary move when the passed argument is an lvalue.
Approach 2<https://gist.github.com/SuperV1234/6509614#multiple-constructors-pass-by-const-and->Multiple
constructors: pass by 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} { } };
- *Passed argument is a temporary*: it is moved without copies. *Result:
1 move.
**Passed argument is an lvalue*: it is just copied. *Result: 1 copy.*
-
*Pros*: most efficient behavior and code generation<http://stackoverflow.com/a/18674317/598696>
.
*Cons*: requires *n^2* constructors/functions written by the developer!
------------------------------
<https://gist.github.com/SuperV1234/6509614#proposal-passing-with-stdsinkt-by-value---behaves-identically-to-approach-2-avoids-code-duplication>Proposal:
passing with std::sink<T>by value - behaves identically to *Approach 2*,
avoids code duplication
struct Example {
std::string s1, s2;
Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{mS1}, s2{mS2} { } };
The above code behaves as if the user had written n^2 constructors
similarly to Approach 2.
*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_235_28579229.1378826958240
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p style=3D"margin-bottom: 15px; color: rgb(0, 0, 0); font=
-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; li=
ne-height: 25px;"><em>Inspired by my own StackOverflow question</em>: =
<a href=3D"http://stackoverflow.com/questions/18673658/should-i-always-move=
-on-sink-constructor-or-setter-arguments" style=3D"color: rgb(65, 131, 196)=
;">Should I always move on <em>sink</em> constructor or setter ar=
guments?</a></p><h1 style=3D"font-size: 2.5em; margin-top: 1em; margin-bott=
om: 15px; text-rendering: optimizelegibility; font-weight: bold; line-heigh=
t: 1.7; cursor: text; position: relative; border-bottom-width: 1px; border-=
bottom-style: solid; border-bottom-color: rgb(221, 221, 221); color: rgb(0,=
0, 0); font-family: Helvetica, arial, freesans, clean, sans-serif;"><a nam=
e=3D"problem-passing-sink-arguments-efficiently-either-requires-performance=
-trade-offs-or-extensive-code-duplication" class=3D"anchor" href=3D"https:/=
/gist.github.com/SuperV1234/6509614#problem-passing-sink-arguments-efficien=
tly-either-requires-performance-trade-offs-or-extensive-code-duplication" s=
tyle=3D"color: rgb(65, 131, 196); display: block; padding-left: 30px; margi=
n-left: -30px; cursor: pointer; position: absolute; top: 0px; left: 0px; bo=
ttom: 0px;"><span class=3D"mini-icon mini-icon-link"></span></a>Problem: pa=
ssing <em>sink</em> arguments efficiently either requires perform=
ance trade-offs or extensive code duplication</h1><h2 style=3D"text-renderi=
ng: optimizelegibility; margin-top: 1em; margin-bottom: 15px; font-weight: =
bold; line-height: 1.7; cursor: text; position: relative; font-size: 2em; b=
order-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: r=
gb(238, 238, 238); color: rgb(0, 0, 0); font-family: Helvetica, arial, free=
sans, clean, sans-serif;"><a name=3D"current-possible-approaches" class=3D"=
anchor" href=3D"https://gist.github.com/SuperV1234/6509614#current-possible=
-approaches" style=3D"color: rgb(65, 131, 196); display: block; padding-lef=
t: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0px;=
left: 0px; bottom: 0px;"><span class=3D"mini-icon mini-icon-link"></span><=
/a>Current possible approaches</h2><h3 style=3D"text-rendering: optimizeleg=
ibility; margin-top: 1em; margin-bottom: 15px; cursor: text; position: rela=
tive; font-family: Helvetica, arial, freesans, clean, sans-serif; line-heig=
ht: 1.7; font-weight: bold; font-size: 1.5em; color: rgb(0, 0, 0);"><a name=
=3D"approach-1" class=3D"anchor" href=3D"https://gist.github.com/SuperV1234=
/6509614#approach-1" style=3D"color: rgb(65, 131, 196); display: block; pad=
ding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; t=
op: 0px; left: 0px; bottom: 0px;"><span class=3D"mini-icon mini-icon-link">=
</span></a>Approach 1</h3><h4 style=3D"text-rendering: optimizelegibility; =
margin-top: 1em; margin-bottom: 15px; font-weight: bold; line-height: 1.7; =
cursor: text; position: relative; font-size: 1.2em; color: rgb(0, 0, 0); fo=
nt-family: Helvetica, arial, freesans, clean, sans-serif;"><a name=3D"pass-=
by-value-and-stdmove" class=3D"anchor" href=3D"https://gist.github.com/Supe=
rV1234/6509614#pass-by-value-and-stdmove" style=3D"color: rgb(65, 131, 196)=
; display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; =
position: absolute; top: 0px; left: 0px; bottom: 0px;"><span class=3D"mini-=
icon mini-icon-link"></span></a>Pass by value and <code style=3D"font-=
family: Consolas, 'Liberation Mono', Courier, monospace; font-size: inherit=
; font-weight: normal; line-height: normal; margin-right: 2px; margin-left:=
2px; padding-right: 5px; padding-left: 5px; border: 1px solid rgb(221, 221=
, 221); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; =
border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-botto=
m-left-radius: 3px; white-space: nowrap;">std::move</code></h4><div class=
=3D"highlight" style=3D"color: rgb(0, 0, 0); font-family: Helvetica, arial,=
freesans, clean, sans-serif; font-size: 15px; line-height: 25px;"><pre sty=
le=3D"font-family: Consolas, 'Liberation Mono', Courier, monospace; font-si=
ze: 13px; line-height: 19px; margin-top: 15px; margin-bottom: 15px; backgro=
und-color: rgb(248, 248, 248); border: 1px solid rgb(221, 221, 221); overfl=
ow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-=
radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3p=
x;"><span class=3D"k" style=3D"font-weight: bold;">struct</span> <span clas=
s=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span> <span class=3D"p">=
{</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span cla=
ss=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"c=
olor: rgb(51, 51, 51);">string</span> <span class=3D"n" style=3D"color: rgb=
(51, 51, 51);">s1</span><span class=3D"p">,</span> <span class=3D"n" style=
=3D"color: rgb(51, 51, 51);">s2</span><span class=3D"p">;</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">st=
d</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">string</span> <span class=3D"n" st=
yle=3D"color: rgb(51, 51, 51);">mS1</span><span class=3D"p">,</span> <span =
class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span class=3D"o" s=
tyle=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"color: rgb(=
51, 51, 51);">string</span> <span class=3D"n" style=3D"color: rgb(51, 51, 5=
1);">mS2</span><span class=3D"p">)</span> <span class=3D"o" style=3D"font-w=
eight: bold;">:</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">=
s1</span><span class=3D"p">{</span><span class=3D"n" style=3D"color: rgb(51=
, 51, 51);">std</span><span class=3D"o" style=3D"font-weight: bold;">::</sp=
an><span class=3D"n" style=3D"color: rgb(51, 51, 51);">move</span><span cla=
ss=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS1</s=
pan><span class=3D"p">)},</span> <span class=3D"n" style=3D"color: rgb(51, =
51, 51);">s2</span><span class=3D"p">{</span><span class=3D"n" style=3D"col=
or: rgb(51, 51, 51);">std</span><span class=3D"o" style=3D"font-weight: bol=
d;">::</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">move</span=
><span class=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51=
);">mS2</span><span class=3D"p">)}</span> <span class=3D"p">{</span> <span =
class=3D"p">}</span>=20
<span class=3D"p">};</span>
</pre></div><ul style=3D"margin: 15px 0px; padding: 0px 0px 0px 30px; font-=
family: Helvetica, arial, freesans, clean, sans-serif;"><li style=3D"color:=
rgb(0, 0, 0);"><font size=3D"2"><strong style=3D"line-height: 25px;">Passe=
d argument is a temporary</strong><span style=3D"line-height: 25px;">: it i=
s moved without copies. </span></font><strong><span style=3D"line-heig=
ht: 25px;"><font size=3D"2">Result: 1 move.</font></span><span style=3D"fon=
t-size: 15.555556297302246px;"><br></span></strong><strong style=3D"font-si=
ze: 13px; line-height: 18px;">Passed argument is an lvalue</strong><span st=
yle=3D"font-size: 13px; line-height: 18px;">: it is copied, then moved.</sp=
an><span style=3D"font-size: 13px; line-height: 18px;"> </span><strong=
style=3D"font-size: 13px; line-height: 18px;">Result: 1 copy + 1 move.</st=
rong></li><li style=3D"font-size: 15px; line-height: 25px;"><p style=3D"mar=
gin-top: 15px; margin-bottom: 15px;"><strong style=3D"color: rgb(0, 0, 0);"=
>Pros</strong><font color=3D"#000000">: no code duplication.<br></font><str=
ong style=3D"color: rgb(0, 0, 0); font-size: 13px; line-height: 18px;">Cons=
</strong><span style=3D"color: rgb(0, 0, 0); font-size: 13px; line-height: =
18px;">: unnecessary move when the passed argument is an lvalue.</span></p>=
</li></ul><h3 style=3D"text-rendering: optimizelegibility; margin-top: 1em;=
margin-bottom: 15px; font-weight: bold; line-height: 1.7; cursor: text; po=
sition: relative; font-size: 1.5em; color: rgb(0, 0, 0); font-family: Helve=
tica, arial, freesans, clean, sans-serif;">Approach 2</h3><h4 style=3D"text=
-rendering: optimizelegibility; margin-top: 1em; margin-bottom: 15px; font-=
weight: bold; line-height: 1.7; cursor: text; position: relative; font-size=
: 1.2em; color: rgb(0, 0, 0); font-family: Helvetica, arial, freesans, clea=
n, sans-serif;"><a name=3D"multiple-constructors-pass-by-const-and-" class=
=3D"anchor" href=3D"https://gist.github.com/SuperV1234/6509614#multiple-con=
structors-pass-by-const-and-" style=3D"color: rgb(65, 131, 196); display: b=
lock; padding-left: 30px; margin-left: -30px; cursor: pointer; position: ab=
solute; top: 0px; left: 0px; bottom: 0px;"><span class=3D"mini-icon mini-ic=
on-link"></span></a>Multiple constructors: pass by <code style=3D"font=
-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: inheri=
t; font-weight: normal; line-height: normal; margin-right: 2px; margin-left=
: 2px; padding-right: 5px; padding-left: 5px; border: 1px solid rgb(221, 22=
1, 221); background-color: rgb(248, 248, 248); border-top-left-radius: 3px;=
border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bott=
om-left-radius: 3px; white-space: nowrap;">const&</code> and =
<code style=3D"font-family: Consolas, 'Liberation Mono', Courier, monospace=
; font-size: inherit; font-weight: normal; line-height: normal; margin-righ=
t: 2px; margin-left: 2px; padding-right: 5px; padding-left: 5px; border: 1p=
x solid rgb(221, 221, 221); background-color: rgb(248, 248, 248); border-to=
p-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radiu=
s: 3px; border-bottom-left-radius: 3px; white-space: nowrap;">&&</c=
ode></h4><div class=3D"highlight" style=3D"color: rgb(0, 0, 0); font-family=
: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-heig=
ht: 25px;"><pre style=3D"font-family: Consolas, 'Liberation Mono', Courier,=
monospace; font-size: 13px; line-height: 19px; margin-top: 15px; margin-bo=
ttom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(221=
, 221, 221); overflow: auto; padding: 6px 10px; border-top-left-radius: 3px=
; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bot=
tom-left-radius: 3px;"><span class=3D"k" style=3D"font-weight: bold;">struc=
t</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span>=
<span class=3D"p">{</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span cla=
ss=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"c=
olor: rgb(51, 51, 51);">string</span> <span class=3D"n" style=3D"color: rgb=
(51, 51, 51);">s1</span><span class=3D"p">,</span> <span class=3D"n" style=
=3D"color: rgb(51, 51, 51);">s2</span><span class=3D"p">;</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">st=
d</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">string</span><span class=3D"o" sty=
le=3D"font-weight: bold;">&&</span> <span class=3D"n" style=3D"colo=
r: rgb(51, 51, 51);">mS1</span><span class=3D"p">,</span> <span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span class=3D"o" style=
=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"color: rgb(51, =
51, 51);">string</span><span class=3D"o" style=3D"font-weight: bold;">&=
&</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</span>=
<span class=3D"p">)</span> <span class=3D"o" style=3D"font-weight: bol=
d;">:</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">s1</span><=
span class=3D"p">{</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);=
">std</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span c=
lass=3D"n" style=3D"color: rgb(51, 51, 51);">move</span><span class=3D"p">(=
</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS1</span><span =
class=3D"p">)},</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">=
s2</span><span class=3D"p">{</span><span class=3D"n" style=3D"color: rgb(51=
, 51, 51);">std</span><span class=3D"o" style=3D"font-weight: bold;">::</sp=
an><span class=3D"n" style=3D"color: rgb(51, 51, 51);">move</span><span cla=
ss=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</s=
pan><span class=3D"p">)}</span> <span class=3D"p">{</span> <span class=3D"p=
">}</span>=20
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"k" style=3D"font-weight: bold;">const</=
span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span c=
lass=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D=
"color: rgb(51, 51, 51);">string</span><span class=3D"o" style=3D"font-weig=
ht: bold;">&</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);"=
>mS1</span><span class=3D"p">,</span> <span class=3D"n" style=3D"color: rgb=
(51, 51, 51);">std</span><span class=3D"o" style=3D"font-weight: bold;">::<=
/span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">string</span><spa=
n class=3D"o" style=3D"font-weight: bold;">&&</span> <span class=3D=
"n" style=3D"color: rgb(51, 51, 51);">mS2</span><span class=3D"p">)</span> =
<span class=3D"o" style=3D"font-weight: bold;">:</span> <span class=3D=
"n" style=3D"color: rgb(51, 51, 51);">s1</span><span class=3D"p">{</span><s=
pan class=3D"n" style=3D"color: rgb(51, 51, 51);">mS1</span><span class=3D"=
p">},</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">s2</span><=
span class=3D"p">{</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);=
">std</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span c=
lass=3D"n" style=3D"color: rgb(51, 51, 51);">move</span><span class=3D"p">(=
</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</span><span =
class=3D"p">)}</span> <span class=3D"p">{</span> <span class=3D"p">}</span>=
=20
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">st=
d</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">string</span><span class=3D"o" sty=
le=3D"font-weight: bold;">&&</span> <span class=3D"n" style=3D"colo=
r: rgb(51, 51, 51);">mS1</span><span class=3D"p">,</span> <span class=
=3D"k" style=3D"font-weight: bold;">const</span> <span class=3D"n" style=3D=
"color: rgb(51, 51, 51);">std</span><span class=3D"o" style=3D"font-weight:=
bold;">::</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">string=
</span><span class=3D"o" style=3D"font-weight: bold;">&</span> <span cl=
ass=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</span><span class=3D"p">)</=
span> <span class=3D"o" style=3D"font-weight: bold;">:</span> <span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">s1</span><span class=3D"p">{</span=
><span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span class=
=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"col=
or: rgb(51, 51, 51);">move</span><span class=3D"p">(</span><span class=3D"n=
" style=3D"color: rgb(51, 51, 51);">mS1</span><span class=3D"p">)},</span> =
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">s2</span><span class=3D=
"p">{</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</span><=
span class=3D"p">}</span> <span class=3D"p">{</span> <span class=3D"p">}</s=
pan>=20
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"k" style=3D"font-weight: bold;">const</=
span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span c=
lass=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D=
"color: rgb(51, 51, 51);">string</span><span class=3D"o" style=3D"font-weig=
ht: bold;">&</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);"=
>mS1</span><span class=3D"p">,</span> <span class=3D"k" style=3D"font-weigh=
t: bold;">const</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">=
std</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span cla=
ss=3D"n" style=3D"color: rgb(51, 51, 51);">string</span><span class=3D"o" s=
tyle=3D"font-weight: bold;">&</span> <span class=3D"n" style=3D"color: =
rgb(51, 51, 51);">mS2</span><span class=3D"p">)</span> <span class=3D"o" st=
yle=3D"font-weight: bold;">:</span> <span class=3D"n" style=3D"color: rgb(5=
1, 51, 51);">s1</span><span class=3D"p">{</span><span class=3D"n" style=3D"=
color: rgb(51, 51, 51);">mS1</span><span class=3D"p">},</span> <span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">s2</span><span class=3D"p">{</span=
><span class=3D"n" style=3D"color: rgb(51, 51, 51);">mS2</span><span class=
=3D"p">}</span> <span class=3D"p">{</span> <span class=3D"p">}</span>=20
<span class=3D"p">};</span>
</pre></div><ul style=3D"margin: 15px 0px; padding: 0px 0px 0px 30px; font-=
family: Helvetica, arial, freesans, clean, sans-serif;"><li style=3D"color:=
rgb(0, 0, 0);"><font size=3D"2"><strong style=3D"line-height: 25px;">Passe=
d argument is a temporary</strong><span style=3D"line-height: 25px;">: it i=
s moved without copies. </span><strong><span style=3D"line-height: 25p=
x;">Result: 1 move.</span><br></strong></font><strong style=3D"line-height:=
18px; font-size: 13px;">Passed argument is an lvalue</strong><span style=
=3D"line-height: 18px; font-size: 13px;">: it is just copied.</span><span s=
tyle=3D"line-height: 18px; font-size: 13px;"> </span><strong style=3D"=
line-height: 18px; font-size: 13px;">Result: 1 copy.</strong></li><li style=
=3D"line-height: 25px; font-size: 15px;"><p style=3D"margin-top: 15px; marg=
in-bottom: 15px;"><strong style=3D"color: rgb(0, 0, 0);">Pros</strong><font=
color=3D"#000000">: </font><a href=3D"http://stackoverflow.com/a/1867=
4317/598696" style=3D"color: rgb(65, 131, 196);">most efficient behavior an=
d code generation</a><font color=3D"#000000">.<br></font><strong style=3D"c=
olor: rgb(0, 0, 0); font-size: 13px; line-height: 18px;">Cons</strong><span=
style=3D"color: rgb(0, 0, 0); font-size: 13px; line-height: 18px;">: requi=
res</span><span style=3D"color: rgb(0, 0, 0); font-size: 13px; line-height:=
18px;"> </span><strong style=3D"color: rgb(0, 0, 0); font-size: 13px;=
line-height: 18px;">n^2</strong><span style=3D"color: rgb(0, 0, 0); font-s=
ize: 13px; line-height: 18px;"> </span><span style=3D"color: rgb(0, 0,=
0); font-size: 13px; line-height: 18px;">constructors/functions written by=
the developer!</span></p></li></ul><hr style=3D"box-sizing: content-box; h=
eight: 4px; background-image: url(https://gist.github.com/assets/primer/mar=
kdown/dirty-shade-95b42666696ad2a6e8a29ba5d93d0797.png); background-color: =
transparent; border: 0px none; color: rgb(204, 204, 204); padding: 0px; mar=
gin: 15px 0px; font-family: Helvetica, arial, freesans, clean, sans-serif; =
font-size: 15px; line-height: 25px; background-position: 0px 0px; backgroun=
d-repeat: repeat no-repeat;"><h1 style=3D"font-size: 2.5em; margin-top: 1em=
; margin-bottom: 15px; text-rendering: optimizelegibility; font-weight: bol=
d; line-height: 1.7; cursor: text; position: relative; border-bottom-width:=
1px; border-bottom-style: solid; border-bottom-color: rgb(221, 221, 221); =
color: rgb(0, 0, 0); font-family: Helvetica, arial, freesans, clean, sans-s=
erif;"><a name=3D"proposal-passing-with-stdsinkt-by-value---behaves-identic=
ally-to-approach-2-avoids-code-duplication" class=3D"anchor" href=3D"https:=
//gist.github.com/SuperV1234/6509614#proposal-passing-with-stdsinkt-by-valu=
e---behaves-identically-to-approach-2-avoids-code-duplication" style=3D"col=
or: rgb(65, 131, 196); display: block; padding-left: 30px; margin-left: -30=
px; cursor: pointer; position: absolute; top: 0px; left: 0px; bottom: 0px;"=
><span class=3D"mini-icon mini-icon-link"></span></a>Proposal: passing with=
<code style=3D"font-family: Consolas, 'Liberation Mono', Courier, mon=
ospace; font-size: inherit; font-weight: normal; line-height: normal; margi=
n-right: 2px; margin-left: 2px; padding-right: 5px; padding-left: 5px; bord=
er: 1px solid rgb(221, 221, 221); background-color: rgb(248, 248, 248); bor=
der-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right=
-radius: 3px; border-bottom-left-radius: 3px; white-space: nowrap;">std::si=
nk<T></code>by value - behaves identically to <strong>Approach 2=
</strong>, avoids code duplication</h1><div class=3D"highlight" style=3D"co=
lor: rgb(0, 0, 0); font-family: Helvetica, arial, freesans, clean, sans-ser=
if; font-size: 15px; line-height: 25px;"><pre style=3D"font-family: Consola=
s, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19p=
x; margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 2=
48); border: 1px solid rgb(221, 221, 221); overflow: auto; padding: 6px 10p=
x; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom=
-right-radius: 3px; border-bottom-left-radius: 3px;"><span class=3D"k" styl=
e=3D"font-weight: bold;">struct</span> <span class=3D"n" style=3D"color: rg=
b(51, 51, 51);">Example</span> <span class=3D"p">{</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span cla=
ss=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"c=
olor: rgb(51, 51, 51);">string</span> <span class=3D"n" style=3D"color: rgb=
(51, 51, 51);">s1</span><span class=3D"p">,</span> <span class=3D"n" style=
=3D"color: rgb(51, 51, 51);">s2</span><span class=3D"p">;</span>
<span class=3D"n" style=3D"color: rgb(51, 51, 51);">Example</span><span=
class=3D"p">(</span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">st=
d</span><span class=3D"o" style=3D"font-weight: bold;">::</span><span class=
=3D"n" style=3D"color: rgb(51, 51, 51);">sink</span><span class=3D"o" style=
=3D"font-weight: bold;"><</span><span class=3D"n" style=3D"color: rgb(51=
, 51, 51);">std</span><span class=3D"o" style=3D"font-weight: bold;">::</sp=
an><span class=3D"n" style=3D"color: rgb(51, 51, 51);">string</span><span c=
lass=3D"o" style=3D"font-weight: bold;">></span> <span class=3D"n" style=
=3D"color: rgb(51, 51, 51);">mS1</span><span class=3D"p">,</span> <span cla=
ss=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span class=3D"o" styl=
e=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"color: rgb(51,=
51, 51);">sink</span><span class=3D"o" style=3D"font-weight: bold;"><</=
span><span class=3D"n" style=3D"color: rgb(51, 51, 51);">std</span><span cl=
ass=3D"o" style=3D"font-weight: bold;">::</span><span class=3D"n" style=3D"=
color: rgb(51, 51, 51);">string</span><span class=3D"o" style=3D"font-weigh=
t: bold;">></span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">m=
S2</span><span class=3D"p">)</span> <span class=3D"o" style=3D"font-weight:=
bold;">:</span> <span class=3D"n" style=3D"color: rgb(51, 51, 51);">s1</sp=
an><span class=3D"p">{</span><span class=3D"n" style=3D"color: rgb(51, 51, =
51);">mS1</span><span class=3D"p">},</span> <span class=3D"n" style=3D"colo=
r: rgb(51, 51, 51);">s2</span><span class=3D"p">{</span><span class=3D"n" s=
tyle=3D"color: rgb(51, 51, 51);">mS2</span><span class=3D"p">}</span> <span=
class=3D"p">{</span> <span class=3D"p">}</span>=20
<span class=3D"p">};</span>
</pre></div><p style=3D"margin-top: 15px; margin-bottom: 15px; color: rgb(0=
, 0, 0); font-family: Helvetica, arial, freesans, clean, sans-serif; font-s=
ize: 15px; line-height: 25px;">The above code behaves as if the user had wr=
itten n^2 constructors similarly to Approach 2.</p><p style=3D"margin-top: =
15px; margin-bottom: 15px; color: rgb(0, 0, 0); font-family: Helvetica, ari=
al, freesans, clean, sans-serif; font-size: 15px; line-height: 25px;"><em>T=
houghts?</em></p></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_235_28579229.1378826958240--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Tue, 10 Sep 2013 17:31:06 +0200
Raw View
On Tue, Sep 10, 2013 at 5:29 PM, Vittorio Romeo
<vittorio.romeo.vee@gmail.com> wrote:
> Inspired by my own StackOverflow question: Should I always move on sink
> constructor or setter arguments?
>
> Problem: passing sink arguments efficiently either requires performance
> trade-offs or extensive code duplication
>
> Current possible approaches
>
> Approach 1
>
> Pass by value and std::move
>
> struct Example {
> std::string s1, s2;
> Example(std::string mS1, std::string mS2) : s1{std::move(mS1)},
> s2{std::move(mS2)} { }
> };
>
> Passed argument is a temporary: it is moved without copies. Result: 1 move.
> Passed argument is an lvalue: it is copied, then moved. Result: 1 copy + 1
> move.
>
> Pros: no code duplication.
> Cons: unnecessary move when the passed argument is an lvalue.
>
> Approach 2
>
> Multiple constructors: pass by 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} { }
> };
>
> Passed argument is a temporary: it is moved without copies. Result: 1 move.
> Passed argument is an lvalue: it is just copied. Result: 1 copy.
>
> Pros: most efficient behavior and code generation.
> Cons: requires n^2 constructors/functions written by the developer!
>
> ________________________________
>
> Proposal: passing with std::sink<T>by value - behaves identically to
> Approach 2, avoids code duplication
>
> struct Example {
> std::string s1, s2;
> Example(std::sink<std::string> mS1, std::sink<std::string> mS2) :
> s1{mS1}, s2{mS2} { }
> };
>
> The above code behaves as if the user had written n^2 constructors similarly
> to Approach 2.
>
> Thoughts?
>
Erm, no, not without considering approach 3, perfect forwarding, first.
--
---
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/.
.
Author: Vittorio Romeo <vittorio.romeo@outlook.com>
Date: Tue, 10 Sep 2013 17:32:04 +0200
Raw View
--_45d26f08-98aa-4586-b287-022998143127_
Content-Type: text/plain; charset=ISO-8859-1
> Date: Tue, 10 Sep 2013 17:31:06 +0200
> Subject: Re: [std-proposals] std::sink<T> to efficiently pass `sink` arguments
> From: martinho.fernandes@gmail.com
> To: std-proposals@isocpp.org
>
>
> Erm, no, not without considering approach 3, perfect forwarding, first.
How does perfect forwarding help here? Or is it an issue?
--
---
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/.
--_45d26f08-98aa-4586-b287-022998143127_
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'><span style=3D"font-size: 12pt;"=
>> Date: Tue, 10 Sep 2013 17:31:06 +0200</span><br><div>> Subject: Re=
: [std-proposals] std::sink<T> to efficiently pass `sink` arguments<b=
r>> From: martinho.fernandes@gmail.com<br>> To: std-proposals@isocpp.=
org<br>> <br>> <br>> Erm, no, not without considering approach 3, =
perfect forwarding, first.<br><br>How does perfect forwarding help here? Or=
is it an issue?<br><br></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 />
--_45d26f08-98aa-4586-b287-022998143127_--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Tue, 10 Sep 2013 17:36:42 +0200
Raw View
On Tue, Sep 10, 2013 at 5:32 PM, Vittorio Romeo
<vittorio.romeo@outlook.com> wrote:
>> Date: Tue, 10 Sep 2013 17:31:06 +0200
>> Subject: Re: [std-proposals] std::sink<T> to efficiently pass `sink`
>> arguments
>> From: martinho.fernandes@gmail.com
>> To: std-proposals@isocpp.org
>
>>
>>
>> Erm, no, not without considering approach 3, perfect forwarding, first.
>
> How does perfect forwarding help here? Or is it an issue?
Perfect forwarding was added to the language in order to solve the N^2
overloads problem. Of course it can help here.
Mit freundlichen Gr=FC=DFen,
Martinho
--=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/.
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Tue, 10 Sep 2013 08:43:20 -0700
Raw View
On Tue, Sep 10, 2013 at 8:36 AM, Martinho Fernandes
<martinho.fernandes@gmail.com> wrote:
> On Tue, Sep 10, 2013 at 5:32 PM, Vittorio Romeo
> <vittorio.romeo@outlook.com> wrote:
>>> Date: Tue, 10 Sep 2013 17:31:06 +0200
>>> Subject: Re: [std-proposals] std::sink<T> to efficiently pass `sink`
>>> arguments
>>> From: martinho.fernandes@gmail.com
>>> To: std-proposals@isocpp.org
>>
>>>
>>>
>>> Erm, no, not without considering approach 3, perfect forwarding, first.
>>
>> How does perfect forwarding help here? Or is it an issue?
>
> Perfect forwarding was added to the language in order to solve the N^2
> overloads problem. Of course it can help here.
Before saying "of course", please write the code.
--
---
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/.
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 10 Sep 2013 10:44:24 -0500
Raw View
--047d7bd770587eb33804e6096341
Content-Type: text/plain; charset=ISO-8859-1
On 10 September 2013 10:36, Martinho Fernandes <martinho.fernandes@gmail.com
> wrote:
>
> > How does perfect forwarding help here? Or is it an issue?
>
> Perfect forwarding was added to the language in order to solve the N^2
> overloads problem. Of course it can help here.
>
Yeah, but it is a bit painful to use, as you end up needing to make all the
parameters templates and then use SFINAE or Concepts Lite to limit the
damage.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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/.
--047d7bd770587eb33804e6096341
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 10 September 2013 10:36, Martinho Fernandes <span dir=
=3D"ltr"><<a href=3D"mailto:martinho.fernandes@gmail.com" target=3D"_bla=
nk">martinho.fernandes@gmail.com</a>></span> wrote:<br><div class=3D"gma=
il_extra">
<div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D"im"=
><br>
> How does perfect forwarding help here? Or is it an issue?<br>
<br>
</div>Perfect forwarding was added to the language in order to solve the N^=
2<br>
overloads problem. Of course it can help here.<br></blockquote><div><br></d=
iv><div>Yeah, but it is a bit painful to use, as you end up needing to make=
all the parameters templates and then use SFINAE or Concepts Lite to limit=
the damage.<br>
</div></div></div><div class=3D"gmail_extra">-- <br>=A0Nevin ":-)"=
; Liber=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_=
blank">nevin@eviloverlord.com</a>>=A0 (847) 691-1404
</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 />
--047d7bd770587eb33804e6096341--
.
Author: Vittorio Romeo <vittorio.romeo@outlook.com>
Date: Tue, 10 Sep 2013 17:45:13 +0200
Raw View
--_f67c9455-9ec1-4121-9d33-05612b5a45b3_
Content-Type: text/plain; charset=ISO-8859-1
> From: jyasskin@google.com
> Date: Tue, 10 Sep 2013 08:43:20 -0700
> Subject: Re: [std-proposals] std::sink<T> to efficiently pass `sink` arguments
> To: std-proposals@isocpp.org
>
> Before saying "of course", please write the code.
>
Indeed. Also, wouldn't it require to use templates with the so-called universal references?
--
---
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/.
--_f67c9455-9ec1-4121-9d33-05612b5a45b3_
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'><span style=3D"font-size: 12pt;"=
>> From: jyasskin@google.com</span><br><div>> Date: Tue, 10 Sep 2013 =
08:43:20 -0700<br>> Subject: Re: [std-proposals] std::sink<T> to e=
fficiently pass `sink` arguments<br>> To: std-proposals@isocpp.org<br><s=
pan style=3D"font-size: 12pt;">> </span><br>> Before saying "of =
course", please write the code.<br>> <br><br></div><div>Indeed. Also, wo=
uldn't it require to use templates with the so-called universal references?=
</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 />
--_f67c9455-9ec1-4121-9d33-05612b5a45b3_--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Tue, 10 Sep 2013 08:47:26 -0700 (PDT)
Raw View
------=_Part_2080_10921420.1378828046110
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, 10 September 2013 17:44:24 UTC+2, Nevin ":-)" Liber wrote:
> Yeah, but it is a bit painful to use, as you end up needing to make all
> the parameters templates and then use SFINAE or Concepts Lite to limit the
> damage.
>
If that's the case, it's even worse than the n^2 constructor problem.
Also, I think specifying that the argument is gonna be sinked right in the
signature (in my std::sink<T> proposal) clearly expresses the intent, more
so than forwarding or pass-by-value + move idiom.
--
---
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_2080_10921420.1378828046110
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><span style=3D"font-size: 13px;">On Tuesday, 10 September =
2013 17:44:24 UTC+2, Nevin ":-)" Liber wrote:</span><br><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote=
"><div>Yeah, but it is a bit painful to use, as you end up needing to make =
all the parameters templates and then use SFINAE or Concepts Lite to limit =
the damage.</div></div></div></div></blockquote><div><br></div><div>If that=
's the case, it's even worse than the n^2 constructor problem. <br>Also, I =
think specifying that the argument is gonna be sinked right in the signatur=
e (in my std::sink<T> proposal) clearly expresses the intent, more so=
than forwarding or pass-by-value + move idiom.</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_2080_10921420.1378828046110--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Tue, 10 Sep 2013 09:16:49 -0700
Raw View
--001a11c2a12069340104e609d7a1
Content-Type: text/plain; charset=ISO-8859-1
Sounds interesting. How would you implement this though?
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 8:29 AM, Vittorio Romeo <
vittorio.romeo.vee@gmail.com> wrote:
> *Inspired by my own StackOverflow question*: Should I always move on *sink
> * constructor or setter arguments?<http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments>
>
> <https://gist.github.com/SuperV1234/6509614#problem-passing-sink-arguments-efficiently-either-requires-performance-trade-offs-or-extensive-code-duplication>Problem:
> passing *sink* arguments efficiently either requires performance
> trade-offs or extensive code duplication <https://gist.github.com/SuperV1234/6509614#current-possible-approaches>Current
> possible approaches
> <https://gist.github.com/SuperV1234/6509614#approach-1>Approach 1
> <https://gist.github.com/SuperV1234/6509614#pass-by-value-and-stdmove>Pass
> by value and std::move
>
> struct Example {
> std::string s1, s2;
> Example(std::string mS1, std::string mS2) : s1{std::move(mS1)}, s2{std::move(mS2)} { } };
>
>
> - *Passed argument is a temporary*: it is moved without copies. *Result:
> 1 move.
> **Passed argument is an lvalue*: it is copied, then moved. *Result: 1
> copy + 1 move.*
> -
>
> *Pros*: no code duplication.
> *Cons*: unnecessary move when the passed argument is an lvalue.
>
> Approach 2
> <https://gist.github.com/SuperV1234/6509614#multiple-constructors-pass-by-const-and->Multiple
> constructors: pass by 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} { } };
>
>
> - *Passed argument is a temporary*: it is moved without copies. *Result:
> 1 move.
> **Passed argument is an lvalue*: it is just copied. *Result: 1 copy.*
> -
>
> *Pros*: most efficient behavior and code generation<http://stackoverflow.com/a/18674317/598696>
> .
> *Cons*: requires *n^2* constructors/functions written by the developer!
>
> ------------------------------
>
> <https://gist.github.com/SuperV1234/6509614#proposal-passing-with-stdsinkt-by-value---behaves-identically-to-approach-2-avoids-code-duplication>Proposal:
> passing with std::sink<T>by value - behaves identically to *Approach 2*,
> avoids code duplication
>
> struct Example {
> std::string s1, s2;
> Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{mS1}, s2{mS2} { } };
>
> The above code behaves as if the user had written n^2 constructors
> similarly to Approach 2.
>
> *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/.
--001a11c2a12069340104e609d7a1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Sounds interesting. How would you implement this thou=
gh?</div></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=
=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/B=
illyONeal/" target=3D"_blank">https://github.com/BillyONeal/</a></div>
<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Tue, Sep 10, 2013 at 8:29 AM, Vittori=
o Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo.vee@gmail.co=
m" target=3D"_blank">vittorio.romeo.vee@gmail.com</a>></span> wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><p style=3D"line-height:25px;font-family:Helvetica,arial,f=
reesans,clean,sans-serif;font-size:15px;margin-bottom:15px"><em>Inspired by=
my own StackOverflow question</em>:=A0<a style=3D"color:rgb(65,131,196)" h=
ref=3D"http://stackoverflow.com/questions/18673658/should-i-always-move-on-=
sink-constructor-or-setter-arguments" target=3D"_blank">Should I always mov=
e on=A0<em>sink</em>=A0constructor or setter arguments?</a></p>
<h1 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:2.5em;font-weight:bold;margin-top:1em;margin-bottom:15px;=
border-bottom-color:rgb(221,221,221);border-bottom-width:1px;border-bottom-=
style:solid">
<a name=3D"141087dbbad0c9b4_problem-passing-sink-arguments-efficiently-eith=
er-requires-performance-trade-offs-or-extensive-code-duplication" style=3D"=
color:rgb(65,131,196);padding-left:30px;display:block" href=3D"https://gist=
..github.com/SuperV1234/6509614#problem-passing-sink-arguments-efficiently-e=
ither-requires-performance-trade-offs-or-extensive-code-duplication" target=
=3D"_blank"><span></span></a>Problem: passing=A0<em>sink</em>=A0arguments e=
fficiently either requires performance trade-offs or extensive code duplica=
tion</h1>
<h2 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:2em;font-weight:bold;margin-top:1em;margin-bottom:15px;bo=
rder-bottom-color:rgb(238,238,238);border-bottom-width:1px;border-bottom-st=
yle:solid">
<a name=3D"141087dbbad0c9b4_current-possible-approaches" style=3D"color:rgb=
(65,131,196);padding-left:30px;display:block" href=3D"https://gist.github.c=
om/SuperV1234/6509614#current-possible-approaches" target=3D"_blank"><span>=
</span></a>Current possible approaches</h2>
<h3 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:1.5em;font-weight:bold;margin-top:1em;margin-bottom:15px"=
><a name=3D"141087dbbad0c9b4_approach-1" style=3D"color:rgb(65,131,196);pad=
ding-left:30px;display:block" href=3D"https://gist.github.com/SuperV1234/65=
09614#approach-1" target=3D"_blank"><span></span></a>Approach 1</h3>
<h4 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:1.2em;font-weight:bold;margin-top:1em;margin-bottom:15px"=
><a name=3D"141087dbbad0c9b4_pass-by-value-and-stdmove" style=3D"color:rgb(=
65,131,196);padding-left:30px;display:block" href=3D"https://gist.github.co=
m/SuperV1234/6509614#pass-by-value-and-stdmove" target=3D"_blank"><span></s=
pan></a>Pass by value and=A0<code style=3D"border-radius:3px;border:1px sol=
id rgb(221,221,221);line-height:normal;padding-right:5px;padding-left:5px;f=
ont-family:Consolas,"Liberation Mono",Courier,monospace;font-size=
:inherit;font-weight:normal;margin-right:2px;margin-left:2px;white-space:no=
wrap;background-color:rgb(248,248,248)">std::move</code></h4>
<div style=3D"line-height:25px;font-family:Helvetica,arial,freesans,clean,s=
ans-serif;font-size:15px"><pre style=3D"padding:6px 10px;border-radius:3px;=
border:1px solid rgb(221,221,221);line-height:19px;overflow:auto;font-famil=
y:Consolas,"Liberation Mono",Courier,monospace;font-size:13px;mar=
gin-top:15px;margin-bottom:15px;background-color:rgb(248,248,248)">
<span style=3D"font-weight:bold">struct</span> <span style=3D"color:rgb(51,=
51,51)">Example</span> <span>{</span>
<span style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weigh=
t:bold">::</span><span style=3D"color:rgb(51,51,51)">string</span> <span st=
yle=3D"color:rgb(51,51,51)">s1</span><span>,</span> <span style=3D"color:rg=
b(51,51,51)">s2</span><span>;</span>
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::<=
/span><span style=3D"color:rgb(51,51,51)">string</span> <span style=3D"colo=
r:rgb(51,51,51)">mS1</span><span>,</span> <span style=3D"color:rgb(51,51,51=
)">std</span><span style=3D"font-weight:bold">::</span><span style=3D"color=
:rgb(51,51,51)">string</span> <span style=3D"color:rgb(51,51,51)">mS2</span=
><span>)</span> <span style=3D"font-weight:bold">:</span> <span style=3D"co=
lor:rgb(51,51,51)">s1</span><span>{</span><span style=3D"color:rgb(51,51,51=
)">std</span><span style=3D"font-weight:bold">::</span><span style=3D"color=
:rgb(51,51,51)">move</span><span>(</span><span style=3D"color:rgb(51,51,51)=
">mS1</span><span>)},</span> <span style=3D"color:rgb(51,51,51)">s2</span><=
span>{</span><span style=3D"color:rgb(51,51,51)">std</span><span style=3D"f=
ont-weight:bold">::</span><span style=3D"color:rgb(51,51,51)">move</span><s=
pan>(</span><span style=3D"color:rgb(51,51,51)">mS2</span><span>)}</span> <=
span>{</span> <span>}</span>=20
<span>};</span>
</pre></div><ul style=3D"margin:15px 0px;padding:0px 0px 0px 30px;font-fami=
ly:Helvetica,arial,freesans,clean,sans-serif"><li><font><strong style=3D"li=
ne-height:25px">Passed argument is a temporary</strong><span style=3D"line-=
height:25px">: it is moved without copies.=A0</span></font><strong><span st=
yle=3D"line-height:25px"><font>Result: 1 move.</font></span><span style=3D"=
font-size:15.55px"><br>
</span></strong><strong style=3D"line-height:18px;font-size:13px">Passed ar=
gument is an lvalue</strong><span style=3D"line-height:18px;font-size:13px"=
>: it is copied, then moved.</span><span style=3D"line-height:18px;font-siz=
e:13px">=A0</span><strong style=3D"line-height:18px;font-size:13px">Result:=
1 copy + 1 move.</strong></li>
<li style=3D"line-height:25px;font-size:15px"><p style=3D"margin-top:15px;m=
argin-bottom:15px"><strong>Pros</strong><font color=3D"#000000">: no code d=
uplication.<br></font><strong style=3D"line-height:18px;font-size:13px">Con=
s</strong><span style=3D"line-height:18px;font-size:13px">: unnecessary mov=
e when the passed argument is an lvalue.</span></p>
</li></ul><h3 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans=
,clean,sans-serif;font-size:1.5em;font-weight:bold;margin-top:1em;margin-bo=
ttom:15px">Approach 2</h3><h4 style=3D"line-height:1.7;font-family:Helvetic=
a,arial,freesans,clean,sans-serif;font-size:1.2em;font-weight:bold;margin-t=
op:1em;margin-bottom:15px">
<a name=3D"141087dbbad0c9b4_multiple-constructors-pass-by-const-and-" style=
=3D"color:rgb(65,131,196);padding-left:30px;display:block" href=3D"https://=
gist.github.com/SuperV1234/6509614#multiple-constructors-pass-by-const-and-=
" target=3D"_blank"><span></span></a>Multiple constructors: pass by=A0<code=
style=3D"border-radius:3px;border:1px solid rgb(221,221,221);line-height:n=
ormal;padding-right:5px;padding-left:5px;font-family:Consolas,"Liberat=
ion Mono",Courier,monospace;font-size:inherit;font-weight:normal;margi=
n-right:2px;margin-left:2px;white-space:nowrap;background-color:rgb(248,248=
,248)">const&</code>=A0and=A0<code style=3D"border-radius:3px;border:1p=
x solid rgb(221,221,221);line-height:normal;padding-right:5px;padding-left:=
5px;font-family:Consolas,"Liberation Mono",Courier,monospace;font=
-size:inherit;font-weight:normal;margin-right:2px;margin-left:2px;white-spa=
ce:nowrap;background-color:rgb(248,248,248)">&&</code></h4>
<div style=3D"line-height:25px;font-family:Helvetica,arial,freesans,clean,s=
ans-serif;font-size:15px"><pre style=3D"padding:6px 10px;border-radius:3px;=
border:1px solid rgb(221,221,221);line-height:19px;overflow:auto;font-famil=
y:Consolas,"Liberation Mono",Courier,monospace;font-size:13px;mar=
gin-top:15px;margin-bottom:15px;background-color:rgb(248,248,248)">
<span style=3D"font-weight:bold">struct</span> <span style=3D"color:rgb(51,=
51,51)">Example</span> <span>{</span>
<span style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weigh=
t:bold">::</span><span style=3D"color:rgb(51,51,51)">string</span> <span st=
yle=3D"color:rgb(51,51,51)">s1</span><span>,</span> <span style=3D"color:rg=
b(51,51,51)">s2</span><span>;</span>
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::<=
/span><span style=3D"color:rgb(51,51,51)">string</span><span style=3D"font-=
weight:bold">&&</span> <span style=3D"color:rgb(51,51,51)">mS1</spa=
n><span>,</span> <span style=3D"color:rgb(51,51,51)">std</span><span s=
tyle=3D"font-weight:bold">::</span><span style=3D"color:rgb(51,51,51)">stri=
ng</span><span style=3D"font-weight:bold">&&</span> <span style=3D"=
color:rgb(51,51,51)">mS2</span><span>)</span> <span style=3D"font-weig=
ht:bold">:</span> <span style=3D"color:rgb(51,51,51)">s1</span><span>{</spa=
n><span style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:=
bold">::</span><span style=3D"color:rgb(51,51,51)">move</span><span>(</span=
><span style=3D"color:rgb(51,51,51)">mS1</span><span>)},</span> <span style=
=3D"color:rgb(51,51,51)">s2</span><span>{</span><span style=3D"color:rgb(51=
,51,51)">std</span><span style=3D"font-weight:bold">::</span><span style=3D=
"color:rgb(51,51,51)">move</span><span>(</span><span style=3D"color:rgb(51,=
51,51)">mS2</span><span>)}</span> <span>{</span> <span>}</span>=20
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"font-weight:bold">const</span> <span style=3D"color:rgb(51,51,51)">=
std</span><span style=3D"font-weight:bold">::</span><span style=3D"color:rg=
b(51,51,51)">string</span><span style=3D"font-weight:bold">&</span> <sp=
an style=3D"color:rgb(51,51,51)">mS1</span><span>,</span> <span style=3D"co=
lor:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::</span><spa=
n style=3D"color:rgb(51,51,51)">string</span><span style=3D"font-weight:bol=
d">&&</span> <span style=3D"color:rgb(51,51,51)">mS2</span><span>)<=
/span> <span style=3D"font-weight:bold">:</span> <span style=3D"color:=
rgb(51,51,51)">s1</span><span>{</span><span style=3D"color:rgb(51,51,51)">m=
S1</span><span>},</span> <span style=3D"color:rgb(51,51,51)">s2</span><span=
>{</span><span style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-=
weight:bold">::</span><span style=3D"color:rgb(51,51,51)">move</span><span>=
(</span><span style=3D"color:rgb(51,51,51)">mS2</span><span>)}</span> <span=
>{</span> <span>}</span>=20
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::<=
/span><span style=3D"color:rgb(51,51,51)">string</span><span style=3D"font-=
weight:bold">&&</span> <span style=3D"color:rgb(51,51,51)">mS1</spa=
n><span>,</span> <span style=3D"font-weight:bold">const</span> <span s=
tyle=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::<=
/span><span style=3D"color:rgb(51,51,51)">string</span><span style=3D"font-=
weight:bold">&</span> <span style=3D"color:rgb(51,51,51)">mS2</span><sp=
an>)</span> <span style=3D"font-weight:bold">:</span> <span style=3D"color:=
rgb(51,51,51)">s1</span><span>{</span><span style=3D"color:rgb(51,51,51)">s=
td</span><span style=3D"font-weight:bold">::</span><span style=3D"color:rgb=
(51,51,51)">move</span><span>(</span><span style=3D"color:rgb(51,51,51)">mS=
1</span><span>)},</span> <span style=3D"color:rgb(51,51,51)">s2</span><span=
>{</span><span style=3D"color:rgb(51,51,51)">mS2</span><span>}</span> <span=
>{</span> <span>}</span>=20
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"font-weight:bold">const</span> <span style=3D"color:rgb(51,51,51)">=
std</span><span style=3D"font-weight:bold">::</span><span style=3D"color:rg=
b(51,51,51)">string</span><span style=3D"font-weight:bold">&</span> <sp=
an style=3D"color:rgb(51,51,51)">mS1</span><span>,</span> <span style=3D"fo=
nt-weight:bold">const</span> <span style=3D"color:rgb(51,51,51)">std</span>=
<span style=3D"font-weight:bold">::</span><span style=3D"color:rgb(51,51,51=
)">string</span><span style=3D"font-weight:bold">&</span> <span style=
=3D"color:rgb(51,51,51)">mS2</span><span>)</span> <span style=3D"font-weigh=
t:bold">:</span> <span style=3D"color:rgb(51,51,51)">s1</span><span>{</span=
><span style=3D"color:rgb(51,51,51)">mS1</span><span>},</span> <span style=
=3D"color:rgb(51,51,51)">s2</span><span>{</span><span style=3D"color:rgb(51=
,51,51)">mS2</span><span>}</span> <span>{</span> <span>}</span>=20
<span>};</span>
</pre></div><ul style=3D"margin:15px 0px;padding:0px 0px 0px 30px;font-fami=
ly:Helvetica,arial,freesans,clean,sans-serif"><li><font><strong style=3D"li=
ne-height:25px">Passed argument is a temporary</strong><span style=3D"line-=
height:25px">: it is moved without copies.=A0</span><strong><span style=3D"=
line-height:25px">Result: 1 move.</span><br>
</strong></font><strong style=3D"line-height:18px;font-size:13px">Passed ar=
gument is an lvalue</strong><span style=3D"line-height:18px;font-size:13px"=
>: it is just copied.</span><span style=3D"line-height:18px;font-size:13px"=
>=A0</span><strong style=3D"line-height:18px;font-size:13px">Result: 1 copy=
..</strong></li>
<li style=3D"line-height:25px;font-size:15px"><p style=3D"margin-top:15px;m=
argin-bottom:15px"><strong>Pros</strong><font color=3D"#000000">:=A0</font>=
<a style=3D"color:rgb(65,131,196)" href=3D"http://stackoverflow.com/a/18674=
317/598696" target=3D"_blank">most efficient behavior and code generation</=
a><font color=3D"#000000">.<br>
</font><strong style=3D"line-height:18px;font-size:13px">Cons</strong><span=
style=3D"line-height:18px;font-size:13px">: requires</span><span style=3D"=
line-height:18px;font-size:13px">=A0</span><strong style=3D"line-height:18p=
x;font-size:13px">n^2</strong><span style=3D"line-height:18px;font-size:13p=
x">=A0</span><span style=3D"line-height:18px;font-size:13px">constructors/f=
unctions written by the developer!</span></p>
</li></ul><hr style=3D"margin:15px 0px;padding:0px;border:0px currentColor;=
color:rgb(204,204,204);line-height:25px;font-family:Helvetica,arial,freesan=
s,clean,sans-serif;font-size:15px;min-height:4px;background-image:none;back=
ground-repeat:repeat no-repeat;background-color:transparent">
<h1 style=3D"line-height:1.7;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:2.5em;font-weight:bold;margin-top:1em;margin-bottom:15px;=
border-bottom-color:rgb(221,221,221);border-bottom-width:1px;border-bottom-=
style:solid">
<a name=3D"141087dbbad0c9b4_proposal-passing-with-stdsinkt-by-value---behav=
es-identically-to-approach-2-avoids-code-duplication" style=3D"color:rgb(65=
,131,196);padding-left:30px;display:block" href=3D"https://gist.github.com/=
SuperV1234/6509614#proposal-passing-with-stdsinkt-by-value---behaves-identi=
cally-to-approach-2-avoids-code-duplication" target=3D"_blank"><span></span=
></a>Proposal: passing with=A0<code style=3D"border-radius:3px;border:1px s=
olid rgb(221,221,221);line-height:normal;padding-right:5px;padding-left:5px=
;font-family:Consolas,"Liberation Mono",Courier,monospace;font-si=
ze:inherit;font-weight:normal;margin-right:2px;margin-left:2px;white-space:=
nowrap;background-color:rgb(248,248,248)">std::sink<T></code>by value=
- behaves identically to=A0<strong>Approach 2</strong>, avoids code duplic=
ation</h1>
<div style=3D"line-height:25px;font-family:Helvetica,arial,freesans,clean,s=
ans-serif;font-size:15px"><pre style=3D"padding:6px 10px;border-radius:3px;=
border:1px solid rgb(221,221,221);line-height:19px;overflow:auto;font-famil=
y:Consolas,"Liberation Mono",Courier,monospace;font-size:13px;mar=
gin-top:15px;margin-bottom:15px;background-color:rgb(248,248,248)">
<span style=3D"font-weight:bold">struct</span> <span style=3D"color:rgb(51,=
51,51)">Example</span> <span>{</span>
<span style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weigh=
t:bold">::</span><span style=3D"color:rgb(51,51,51)">string</span> <span st=
yle=3D"color:rgb(51,51,51)">s1</span><span>,</span> <span style=3D"color:rg=
b(51,51,51)">s2</span><span>;</span>
<span style=3D"color:rgb(51,51,51)">Example</span><span>(</span><span s=
tyle=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::<=
/span><span style=3D"color:rgb(51,51,51)">sink</span><span style=3D"font-we=
ight:bold"><</span><span style=3D"color:rgb(51,51,51)">std</span><span s=
tyle=3D"font-weight:bold">::</span><span style=3D"color:rgb(51,51,51)">stri=
ng</span><span style=3D"font-weight:bold">></span> <span style=3D"color:=
rgb(51,51,51)">mS1</span><span>,</span> <span style=3D"color:rgb(51,51,51)"=
>std</span><span style=3D"font-weight:bold">::</span><span style=3D"color:r=
gb(51,51,51)">sink</span><span style=3D"font-weight:bold"><</span><span =
style=3D"color:rgb(51,51,51)">std</span><span style=3D"font-weight:bold">::=
</span><span style=3D"color:rgb(51,51,51)">string</span><span style=3D"font=
-weight:bold">></span> <span style=3D"color:rgb(51,51,51)">mS2</span><sp=
an>)</span> <span style=3D"font-weight:bold">:</span> <span style=3D"color:=
rgb(51,51,51)">s1</span><span>{</span><span style=3D"color:rgb(51,51,51)">m=
S1</span><span>},</span> <span style=3D"color:rgb(51,51,51)">s2</span><span=
>{</span><span style=3D"color:rgb(51,51,51)">mS2</span><span>}</span> <span=
>{</span> <span>}</span>=20
<span>};</span>
</pre></div><p style=3D"line-height:25px;font-family:Helvetica,arial,freesa=
ns,clean,sans-serif;font-size:15px;margin-top:15px;margin-bottom:15px">The =
above code behaves as if the user had written n^2 constructors similarly to=
Approach 2.</p>
<p style=3D"line-height:25px;font-family:Helvetica,arial,freesans,clean,san=
s-serif;font-size:15px;margin-top:15px;margin-bottom:15px"><em>Thoughts?</e=
m></p></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 />
--001a11c2a12069340104e609d7a1--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Tue, 10 Sep 2013 09:21:41 -0700 (PDT)
Raw View
------=_Part_352_32326584.1378830101195
Content-Type: text/plain; charset=ISO-8859-1
While looking for a possible solution I found this:
http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-valley-code-camp.html
All the slides are related to the problem, but a possible (albeit, in my
opinion, not perfect) implementation can be found on slide 29.
On Tuesday, 10 September 2013 18:16:49 UTC+2, Billy O'Neal wrote:
>
> Sounds interesting. How would you implement this though?
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
--
---
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_352_32326584.1378830101195
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">While looking for a possible solution I found this:<br><br=
><a href=3D"http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-va=
lley-code-camp.html">http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-s=
ilicon-valley-code-camp.html</a><br><br>All the slides are related to the p=
roblem, but a possible (albeit, in my opinion, not perfect) implementation =
can be found on slide 29.<br><br>On Tuesday, 10 September 2013 18:16:49 UTC=
+2, Billy O'Neal wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div>Sounds interesting. How would you implement this though?</d=
iv></div><div><br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O'Neal</di=
v><div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">http=
s://github.com/BillyONeal/</a></div>
<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/<wbr>users/82320/billy-oneal</a></div><di=
v>Malware Response Instructor - BleepingComputer.com</div></div></div></div=
>
</blockquote></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_352_32326584.1378830101195--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Tue, 10 Sep 2013 10:30:37 -0700
Raw View
--089e01538bc455d97f04e60adff2
Content-Type: text/plain; charset=ISO-8859-1
I'm not sure that implementation works. Presumably you'd want to call the
move member, but that member is not eligible for RVO (does not return the
same variable on all code paths, and does not return rvalues on all code
paths). So you end up just paying the move when moving the return value of
in<T>::move() into the target.
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 9:21 AM, Vittorio Romeo <
vittorio.romeo.vee@gmail.com> wrote:
> While looking for a possible solution I found this:
>
>
> http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-valley-code-camp.html
>
> All the slides are related to the problem, but a possible (albeit, in my
> opinion, not perfect) implementation can be found on slide 29.
>
>
> On Tuesday, 10 September 2013 18:16:49 UTC+2, Billy O'Neal wrote:
>>
>> Sounds interesting. How would you implement this though?
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>> Malware Response Instructor - BleepingComputer.com
>>
> --
>
> ---
> 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/.
--089e01538bc455d97f04e60adff2
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'm not sure that implementation works. Presumably you=
'd want to call the move member, but that member is not eligible for RV=
O (does not return the same variable on all code paths, and does not return=
rvalues on all code paths). So you end up just paying the move when moving=
the return value of in<T>::move() into the target.</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 9:21 AM, Vittori=
o Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo.vee@gmail.co=
m" target=3D"_blank">vittorio.romeo.vee@gmail.com</a>></span> wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<div dir=3D"ltr">While looking for a possible solution I found this:<br><br=
><a href=3D"http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-va=
lley-code-camp.html" target=3D"_blank">http://cpptruths.blogspot.it/2012/10=
/c11-idioms-2012-silicon-valley-code-camp.html</a><br>
<br>All the slides are related to the problem, but a possible (albeit, in m=
y opinion, not perfect) implementation can be found on slide 29.<div class=
=3D"im"><br><br>On Tuesday, 10 September 2013 18:16:49 UTC+2, Billy O'N=
eal wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1=
px;border-left-style:solid">
<div dir=3D"ltr"><div>Sounds interesting. How would you implement this thou=
gh?</div></div><div><br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O=
9;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_b=
lank">https://github.com/BillyONeal/</a></div>
<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div><=
div>Malware Response Instructor - BleepingComputer.com</div></div></div></d=
iv>
</blockquote></div></div>
<p></p>
-- <br><div class=3D"HOEnZb"><div class=3D"h5">
=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>
</div></div></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 />
--089e01538bc455d97f04e60adff2--
.
Author: Vittorio Romeo <vittorio.romeo@outlook.com>
Date: Tue, 10 Sep 2013 19:37:31 +0200
Raw View
--_5bdf8eb1-5724-40cc-b4f2-619223de077c_
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
You're right, I think. Maybe an implementation would require some changes t=
o the core language: my suggestion is something like std::initializer_list,=
it looks like a library-only class but actually is bound to new language i=
deas
From: billy.oneal@gmail.com
Date: Tue, 10 Sep 2013 10:30:37 -0700
Subject: Re: [std-proposals] std::sink<T> to efficiently pass `sink` argume=
nts
To: std-proposals@isocpp.org
I'm not sure that implementation works. Presumably you'd want to call the m=
ove member, but that member is not eligible for RVO (does not return the sa=
me variable on all code paths, and does not return rvalues on all code path=
s). So you end up just paying the move when moving the return value of in<T=
>::move() into the target.
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 9:21 AM, Vittorio Romeo <vittorio.romeo.vee@gmail.c=
om> wrote:
While looking for a possible solution I found this:
http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-valley-code-ca=
mp.html
All the slides are related to the problem, but a possible (albeit, in my op=
inion, not perfect) implementation can be found on slide 29.
On Tuesday, 10 September 2013 18:16:49 UTC+2, Billy O'Neal wrote:
Sounds interesting. How would you implement this though?Billy O'Nealhttps:/=
/github.com/BillyONeal/
http://stackoverflow.com/users/82320/billy-onealMalware Response Instructor=
- BleepingComputer.com
--=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/.
--_5bdf8eb1-5724-40cc-b4f2-619223de077c_
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'>You're right, I think. Maybe an =
implementation would require some changes to the core language: my suggesti=
on is something like std::initializer_list, it looks like a library-only cl=
ass but actually is bound to new language ideas<br><br><div><hr id=3D"stopS=
pelling">From: billy.oneal@gmail.com<br>Date: Tue, 10 Sep 2013 10:30:37 -07=
00<br>Subject: Re: [std-proposals] std::sink<T> to efficiently pass `=
sink` arguments<br>To: std-proposals@isocpp.org<br><br><div dir=3D"ltr">I'm=
not sure that implementation works. Presumably you'd want to call the move=
member, but that member is not eligible for RVO (does not return the same =
variable on all code paths, and does not return rvalues on all code paths).=
So you end up just paying the move when moving the return value of in<T=
>::move() into the target.</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 9:21 AM, Vitt=
orio Romeo <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 class=3D"ecxgmail_quote" style=3D"border-left:1px #ccc solid=
;padding-left:1ex;">
<div dir=3D"ltr">While looking for a possible solution I found this:<br><br=
><a href=3D"http://cpptruths.blogspot.it/2012/10/c11-idioms-2012-silicon-va=
lley-code-camp.html" target=3D"_blank">http://cpptruths.blogspot.it/2012/10=
/c11-idioms-2012-silicon-valley-code-camp.html</a><br>
<br>All the slides are related to the problem, but a possible (albeit, in m=
y opinion, not perfect) implementation can be found on slide 29.<div class=
=3D"ecxim"><br><br>On Tuesday, 10 September 2013 18:16:49 UTC+2, Billy O'Ne=
al wrote:<blockquote class=3D"ecxgmail_quote" style=3D"padding-left:1ex;bo=
rder-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:so=
lid;">
<div dir=3D"ltr"><div>Sounds interesting. How would you implement this thou=
gh?</div></div><div><br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O'Ne=
al</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://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div><=
div>Malware Response Instructor - BleepingComputer.com</div></div></div></d=
iv>
</blockquote></div></div>
<BR>
-- <br><div class=3D"ecxHOEnZb"><div class=3D"h5">
<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>
</div></div></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></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 />
--_5bdf8eb1-5724-40cc-b4f2-619223de077c_--
.
Author: rhalbersma@gmail.com
Date: Tue, 10 Sep 2013 09:04:01 -0700 (PDT)
Raw View
------=_Part_293_28592704.1378829041650
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, September 10, 2013 5:29:18 PM UTC+2, Vittorio Romeo wrote:
>
> -
>
> *Cons*: requires *n^2* constructors/functions written by the developer!
>
>
Actually: 2^N overloads (a factor of 2 for each of the N arguments).
--
---
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_293_28592704.1378829041650
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, September 10, 2013 5:29:18 PM UTC+2, Vittorio =
Romeo wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><ul style=3D"margin:15px 0px;padding:0px 0px 0px 30px;font-family:Helvet=
ica,arial,freesans,clean,sans-serif"><li style=3D"line-height:25px;font-siz=
e:15px"><p style=3D"margin-top:15px;margin-bottom:15px"><strong style=3D"co=
lor:rgb(0,0,0);font-size:13px;line-height:18px">Cons</strong><span style=3D=
"color:rgb(0,0,0);font-size:13px;line-height:18px">: requires</span><span s=
tyle=3D"color:rgb(0,0,0);font-size:13px;line-height:18px"> </span><str=
ong style=3D"color:rgb(0,0,0);font-size:13px;line-height:18px">n^2</strong>=
<span style=3D"color:rgb(0,0,0);font-size:13px;line-height:18px"> </sp=
an><span style=3D"color:rgb(0,0,0);font-size:13px;line-height:18px">constru=
ctors/<wbr>functions written by the developer!</span></p></li></ul></div></=
blockquote><div><br></div><div>Actually: 2^N overloads (a factor of 2 for e=
ach of the N arguments).</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_293_28592704.1378829041650--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Wed, 11 Sep 2013 06:33:13 -0700 (PDT)
Raw View
------=_Part_3044_7802781.1378906393509
Content-Type: text/plain; charset=ISO-8859-1
Sorry for the duplicate thread. As Jonathan Wakely suggested, let's just
use this one to avoid unnecessary duplication.
In the other thread, *Jared Grubb* mentioned:
> 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.
*Jonathan Wakely* replied to him:
> That's already allowed in C++11.
>
This sounds a good solution. However, searching online for "move elision"
returns 0 relevant results.
Can someone confirm this?
--
---
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_3044_7802781.1378906393509
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Sorry for the duplicate thread. As <span class=3D"_us=
ername" style=3D"white-space: nowrap;"><span class=3D"GIVTN-QCJLB">Jonathan=
Wakely</span></span><span style=3D"white-space: nowrap;"> suggested, =
let's just use this one to avoid unnecessary duplication.<br><br>In the oth=
er thread, <b>Jared Grubb</b> mentioned:</span><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;">At GoingNative last week, someone mentioned that "move elision"=
will (probably?) be added to the standard. That means the compiler is allo=
wed to remove moves in the same way compilers are allowed to remove copies.=
<br>I think that would apply to your example, and so the results woul=
d just be "1 move" and "1 copy", respectively. But, ask a guru, since I'm n=
ot 100% certain.</blockquote><div><br></div><div><b>Jonathan Wakely</b>&nbs=
p;replied to him:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, =
204); border-left-style: solid; padding-left: 1ex;">That's already allowed =
in C++11.<br></blockquote><div><br></div><div> This sounds a good solu=
tion. However, searching online for "move elision" returns 0 relevant resul=
ts.</div><div>Can someone confirm this?</div></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_3044_7802781.1378906393509--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Wed, 11 Sep 2013 15:39:50 +0200
Raw View
--047d7bf1985271388e04e61bc186
Content-Type: text/plain; charset=ISO-8859-1
2013/9/11 Vittorio Romeo <vittorio.romeo.vee@gmail.com>
> Sorry for the duplicate thread. As Jonathan Wakely suggested, let's just
> use this one to avoid unnecessary duplication.
>
> In the other thread, *Jared Grubb* mentioned:
>
>> 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.
>
>
> *Jonathan Wakely* replied to him:
>
>> That's already allowed in C++11.
>>
>
> This sounds a good solution. However, searching online for "move elision"
> returns 0 relevant results.
> Can someone confirm this?
>
The standard does not have a separate name for it, so there exists not the
term "move elision". The definition of copy elision starts as follows:
"This elision of copy/move operations, called copy elision, is permitted in
the following circumstances [..]"
- Daniel
--
---
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/.
--047d7bf1985271388e04e61bc186
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2013=
/9/11 Vittorio Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo=
..vee@gmail.com" target=3D"_blank">vittorio.romeo.vee@gmail.com</a>></spa=
n><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">Sorry for the duplicate thread. As=A0<span style=3D"white-=
space:nowrap"><span>Jonathan Wakely</span></span><span style=3D"white-space=
:nowrap">=A0suggested, let's just use this one to avoid unnecessary dup=
lication.<br>
<br>In the other thread, <b>Jared Grubb</b>=A0mentioned:</span><div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex">At GoingNative last week, someon=
e mentioned that "move elision" will (probably?) be added to the =
standard. That means the compiler is allowed to remove moves in the same wa=
y compilers are allowed to remove copies.=A0<br>
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, s=
ince I'm not 100% certain.</blockquote><div><br></div><div><b>Jonathan =
Wakely</b>=A0replied to him:</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">That's already allowe=
d in C++11.<br></blockquote><div><br></div><div>=A0This sounds a good solut=
ion. However, searching online for "move elision" returns 0 relev=
ant results.</div>
<div>Can someone confirm this?</div></div></div></blockquote><div><br></div=
><div>The standard does not have a separate name for it, so there exists no=
t the term "move elision".=A0 The definition of copy elision star=
ts as follows:<br>
<br>"This elision of copy/move operations, called copy elision, is per=
mitted in the following circumstances [..]"<br><br></div><div>- Daniel=
<br></div></div></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 />
--047d7bf1985271388e04e61bc186--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Wed, 11 Sep 2013 09:47:03 -0700
Raw View
--001a11c2a1205d8d8f04e61e6139
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
The standard doesn't allow move elision from xvalues (as described at
G::N). That is, given
expensive_t go()
{
expensive_t result;
return move(result);
}
Implementations aren't allowed to use RVO/NRVO here for the result of
std::move(), even though this would normally be an NRVO candidate.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Wed, Sep 11, 2013 at 6:39 AM, Daniel Kr=FCgler
<daniel.kruegler@gmail.com>wrote:
> 2013/9/11 Vittorio Romeo <vittorio.romeo.vee@gmail.com>
>
>> Sorry for the duplicate thread. As Jonathan Wakely suggested, let's just
>> use this one to avoid unnecessary duplication.
>>
>> In the other thread, *Jared Grubb* mentioned:
>>
>>> At GoingNative last week, someone mentioned that "move elision" will
>>> (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.
>>> 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.
>>
>>
>> *Jonathan Wakely* replied to him:
>>
>>> That's already allowed in C++11.
>>>
>>
>> This sounds a good solution. However, searching online for "move
>> elision" returns 0 relevant results.
>> Can someone confirm this?
>>
>
> The standard does not have a separate name for it, so there exists not th=
e
> term "move elision". The definition of copy elision starts as follows:
>
> "This elision of copy/move operations, called copy elision, is permitted
> in the following circumstances [..]"
>
> - Daniel
>
> --
>
> ---
> 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/.
>
--=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/.
--001a11c2a1205d8d8f04e61e6139
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>The standard doesn't allow move elision from xval=
ues (as described at G::N). That is, given</div><div>=A0</div><div>expensiv=
e_t go()</div><div>{<br>=A0=A0=A0 expensive_t result;</div><div>=A0=A0=A0 r=
eturn move(result);</div>
<div>}<br></div><div>Implementations aren't allowed to use RVO/NRVO her=
e for the result of std::move(), even though this would normally be an NRVO=
candidate.</div><div>=A0</div></div><div class=3D"gmail_extra"><br clear=
=3D"all">
<div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bi=
tbucket.org/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</=
a></div><div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" t=
arget=3D"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Wed, Sep 11, 2013 at 6:39 AM, Daniel =
Kr=FCgler <span dir=3D"ltr"><<a href=3D"mailto:daniel.kruegler@gmail.com=
" target=3D"_blank">daniel.kruegler@gmail.com</a>></span> wrote:<br><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
class=3D"im">2013/9/11 Vittorio Romeo <span dir=3D"ltr"><<a href=3D"mai=
lto:vittorio.romeo.vee@gmail.com" target=3D"_blank">vittorio.romeo.vee@gmai=
l.com</a>></span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
<div dir=3D"ltr">Sorry for the duplicate thread. As=A0<span style=3D"white-=
space:nowrap"><span>Jonathan Wakely</span></span><span style=3D"white-space=
:nowrap">=A0suggested, let's just use this one to avoid unnecessary dup=
lication.<br>
<br>In the other thread, <b>Jared Grubb</b>=A0mentioned:</span><div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1=
ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-sty=
le:solid">
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.=
=A0<br>
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, s=
ince I'm not 100% certain.</blockquote><div><br></div><div><b>Jonathan =
Wakely</b>=A0replied to him:</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">That's already allowed in C++11.<br></blockquote><div>
<br></div><div>=A0This sounds a good solution. However, searching online fo=
r "move elision" returns 0 relevant results.</div>
<div>Can someone confirm this?</div></div></div></blockquote><div><br></div=
></div><div>The standard does not have a separate name for it, so there exi=
sts not the term "move elision".=A0 The definition of copy elisio=
n starts as follows:<br>
<br>"This elision of copy/move operations, called copy elision, is per=
mitted in the following circumstances [..]"<span class=3D"HOEnZb"><fon=
t color=3D"#888888"><br><br></font></span></div><span class=3D"HOEnZb"><fon=
t color=3D"#888888"><div>
- Daniel <br></div></font></span></div></div></div><div class=3D"HOEnZb"><d=
iv class=3D"h5">
<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>
</div></div></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 />
--001a11c2a1205d8d8f04e61e6139--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 11 Sep 2013 10:49:46 -0700
Raw View
--047d7b6721c442b7dd04e61f3f76
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Wed, Sep 11, 2013 at 9:47 AM, Billy O'Neal <billy.oneal@gmail.com> wrote=
:
> The standard doesn't allow move elision from xvalues (as described at
> G::N). That is, given
>
> expensive_t go()
> {
> expensive_t result;
> return move(result);
> }
> Implementations aren't allowed to use RVO/NRVO here for the result of
> std::move(), even though this would normally be an NRVO candidate.
>
See NB comments US12 and US13.
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Wed, Sep 11, 2013 at 6:39 AM, Daniel Kr=FCgler <daniel.kruegler@gmail.=
com
> > wrote:
>
>> 2013/9/11 Vittorio Romeo <vittorio.romeo.vee@gmail.com>
>>
>>> Sorry for the duplicate thread. As Jonathan Wakely suggested, let's
>>> just use this one to avoid unnecessary duplication.
>>>
>>> In the other thread, *Jared Grubb* mentioned:
>>>
>>>> At GoingNative last week, someone mentioned that "move elision" will
>>>> (probably?) be added to the standard. That means the compiler is allow=
ed 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 jus=
t
>>>> be "1 move" and "1 copy", respectively. But, ask a guru, since I'm not=
100%
>>>> certain.
>>>
>>>
>>> *Jonathan Wakely* replied to him:
>>>
>>>> That's already allowed in C++11.
>>>>
>>>
>>> This sounds a good solution. However, searching online for "move
>>> elision" returns 0 relevant results.
>>> Can someone confirm this?
>>>
>>
>> The standard does not have a separate name for it, so there exists not
>> the term "move elision". The definition of copy elision starts as follo=
ws:
>>
>> "This elision of copy/move operations, called copy elision, is permitted
>> in the following circumstances [..]"
>>
>> - Daniel
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/.
>
--=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/.
--047d7b6721c442b7dd04e61f3f76
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wed, Sep 11, 2013 at 9:47 AM, Billy O'Neal <span di=
r=3D"ltr"><<a href=3D"mailto:billy.oneal@gmail.com" target=3D"_blank">bi=
lly.oneal@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><di=
v class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>The standard doesn'=
;t allow move elision from xvalues (as described at G::N). That is, given</=
div>
<div>=A0</div><div>expensive_t go()</div><div>{<br>=A0=A0=A0 expensive_t re=
sult;</div><div>=A0=A0=A0 return move(result);</div>
<div>}<br></div><div>Implementations aren't allowed to use RVO/NRVO her=
e for the result of std::move(), even though this would normally be an NRVO=
candidate.</div></div></blockquote><div><br></div><div>See NB comments US1=
2 and US13.</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div class=3D"gmail_extra"><di=
v class=3D"im">
<div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bi=
tbucket.org/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</=
a></div><div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" t=
arget=3D"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div><div><div class=3D"h5"><div class=3D"gmail_quote">On Wed, Sep=
11, 2013 at 6:39 AM, Daniel Kr=FCgler <span dir=3D"ltr"><<a href=3D"mai=
lto:daniel.kruegler@gmail.com" target=3D"_blank">daniel.kruegler@gmail.com<=
/a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>2013/9/11 Vittorio Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.=
romeo.vee@gmail.com" target=3D"_blank">vittorio.romeo.vee@gmail.com</a>>=
</span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
<div dir=3D"ltr">Sorry for the duplicate thread. As=A0<span style=3D"white-=
space:nowrap"><span>Jonathan Wakely</span></span><span style=3D"white-space=
:nowrap">=A0suggested, let's just use this one to avoid unnecessary dup=
lication.<br>
<br>In the other thread, <b>Jared Grubb</b>=A0mentioned:</span><div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1=
ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-sty=
le:solid">
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.=
=A0<br>
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, s=
ince I'm not 100% certain.</blockquote><div><br></div><div><b>Jonathan =
Wakely</b>=A0replied to him:</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">That's already allowed in C++11.<br></blockquote><div>
<br></div><div>=A0This sounds a good solution. However, searching online fo=
r "move elision" returns 0 relevant results.</div>
<div>Can someone confirm this?</div></div></div></blockquote><div><br></div=
></div><div>The standard does not have a separate name for it, so there exi=
sts not the term "move elision".=A0 The definition of copy elisio=
n starts as follows:<br>
<br>"This elision of copy/move operations, called copy elision, is per=
mitted in the following circumstances [..]"<span><font color=3D"#88888=
8"><br><br></font></span></div><span><font color=3D"#888888"><div>
- Daniel <br></div></font></span></div></div></div><div><div>
<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>
</div></div></blockquote></div><br></div></div></div><div class=3D"HOEnZb">=
<div class=3D"h5">
<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>
</div></div></blockquote></div><br></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 />
--047d7b6721c442b7dd04e61f3f76--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Wed, 11 Sep 2013 20:07:25 +0200
Raw View
--047d7bb045c45fce0704e61f7e7a
Content-Type: text/plain; charset=ISO-8859-1
2013/9/11 Billy O'Neal <billy.oneal@gmail.com>
> The standard doesn't allow move elision from xvalues (as described at
> G::N). That is, given
>
> expensive_t go()
> {
> expensive_t result;
> return move(result);
> }
> Implementations aren't allowed to use RVO/NRVO here for the result of
> std::move(), even though this would normally be an NRVO candidate.
>
That's correct. There exists several proposals to fix that, among them one
that gives std::move() a special meaning for the core language.
That is one of the to clearly specify what someone means. The term "move
elision" alone is not specific enough.
- Daniel
--
---
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/.
--047d7bb045c45fce0704e61f7e7a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
2013/9/11 Billy O'Neal <span dir=3D"ltr"><<a href=3D"mailto:billy.on=
eal@gmail.com" target=3D"_blank">billy.oneal@gmail.com</a>></span><br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div>The standard doesn't allow move elision from xval=
ues (as described at G::N). That is, given</div><div>=A0</div><div>expensiv=
e_t go()</div><div>{<br>=A0=A0=A0 expensive_t result;</div><div>=A0=A0=A0 r=
eturn move(result);</div>
<div>}<br></div><div>Implementations aren't allowed to use RVO/NRVO her=
e for the result of std::move(), even though this would normally be an NRVO=
candidate.</div></div></blockquote><div><br></div><div>That's correct.=
There exists several proposals to fix that, among them one that gives std:=
:move() a special meaning for the core language.<br>
<br></div><div>That is one of the to clearly specify what someone means. Th=
e term "move elision" alone is not specific enough.<br><br></div>=
</div>- Daniel<br><br></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 />
--047d7bb045c45fce0704e61f7e7a--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Thu, 12 Sep 2013 06:01:12 -0700 (PDT)
Raw View
------=_Part_538_8470070.1378990872893
Content-Type: text/plain; charset=ISO-8859-1
I'm confused: is the compiler able to elide or not in this situation?
--
---
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_538_8470070.1378990872893
Content-Type: text/html; charset=ISO-8859-1
<div dir="ltr">I'm confused: is the compiler able to elide or not in this situation?</div>
<p></p>
-- <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 email 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="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_538_8470070.1378990872893--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 12 Sep 2013 15:11:11 +0200
Raw View
--089e0102fb5cd8094904e62f78b9
Content-Type: text/plain; charset=ISO-8859-1
2013/9/12 Vittorio Romeo <vittorio.romeo.vee@gmail.com>
> I'm confused: is the compiler able to elide or not in this situation?
>
It is currently not in this specific situation, but that doesn't mean that
there is no move-elision going on. For example a minor simplification of
above example *does* enable move-elision:
expensive_t go()
{
expensive_t result;
return result;
}
- Daniel
--
---
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/.
--089e0102fb5cd8094904e62f78b9
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2013=
/9/12 Vittorio Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo=
..vee@gmail.com" target=3D"_blank">vittorio.romeo.vee@gmail.com</a>></spa=
n><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">I'm confused: is the compiler able to elide or not in =
this situation?</div></blockquote><div><br></div><div>It is currently not i=
n this specific situation, but that doesn't mean that there is no move-=
elision going on. For example a minor simplification of above example *does=
* enable move-elision:<br>
<br><div>expensive_t go()</div><div>{<br>=A0=A0=A0 expensive_t result;</div=
><div>=A0=A0=A0 return result;</div>
}<br></div></div><br></div><div class=3D"gmail_extra">- Daniel<br><br></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 />
--089e0102fb5cd8094904e62f78b9--
.
Author: Vittorio Romeo <vittorio.romeo@outlook.com>
Date: Thu, 12 Sep 2013 15:28:50 +0200
Raw View
--_b7072cce-665d-4dc5-98df-b059f6cf4efd_
Content-Type: text/plain; charset=ISO-8859-1
That's `traditional` move/copy elision in my book - the typical elision done on return from functions.I'd say it's not a simplification of my examples but a completely different thing.
So I guess not having move-elision on `sink` arguments can still be considered a `defect`.
Date: Thu, 12 Sep 2013 15:11:11 +0200
Subject: Re: [std-proposals] Re: std::sink<T> to efficiently pass `sink` arguments
From: daniel.kruegler@gmail.com
To: std-proposals@isocpp.org
2013/9/12 Vittorio Romeo <vittorio.romeo.vee@gmail.com>
I'm confused: is the compiler able to elide or not in this situation?
It is currently not in this specific situation, but that doesn't mean that there is no move-elision going on. For example a minor simplification of above example *does* enable move-elision:
expensive_t go(){
expensive_t result; return result;
}
- Daniel
--
---
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/.
--_b7072cce-665d-4dc5-98df-b059f6cf4efd_
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'>That's `traditional` move/copy e=
lision in my book - the typical elision done on return from functions.<div>=
I'd say it's not a simplification of my examples but a completely different=
thing.<br><div>So I guess not having move-elision on `sink` arguments can =
still be considered a `defect`.<br><br><br><div><hr id=3D"stopSpelling">Dat=
e: Thu, 12 Sep 2013 15:11:11 +0200<br>Subject: Re: [std-proposals] Re: std:=
:sink<T> to efficiently pass `sink` arguments<br>From: daniel.kruegle=
r@gmail.com<br>To: std-proposals@isocpp.org<br><br><div dir=3D"ltr"><div cl=
ass=3D"ecxgmail_extra"><div class=3D"ecxgmail_quote">2013/9/12 Vittorio Rom=
eo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo.vee@gmail.com" ta=
rget=3D"_blank">vittorio.romeo.vee@gmail.com</a>></span><br><blockquote =
class=3D"ecxgmail_quote" style=3D"border-left:1px solid rgb(204,204,204);pa=
dding-left:1ex;">
<div dir=3D"ltr">I'm confused: is the compiler able to elide or not in this=
situation?</div></blockquote><div><br></div><div>It is currently not in th=
is specific situation, but that doesn't mean that there is no move-elision =
going on. For example a minor simplification of above example *does* enable=
move-elision:<br>
<br><div>expensive_t go()</div><div>{<br> expensive_t res=
ult;</div><div> return result;</div>
}<br></div></div><br></div><div class=3D"ecxgmail_extra">- Daniel<br><br></=
div></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> </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 />
--_b7072cce-665d-4dc5-98df-b059f6cf4efd_--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 12 Sep 2013 16:14:57 +0200
Raw View
--047d7b86f172dfb64204e6305c0d
Content-Type: text/plain; charset=ISO-8859-1
2013/9/12 Vittorio Romeo <vittorio.romeo@outlook.com>
> That's `traditional` move/copy elision in my book - the typical elision
> done on return from functions.
>
Exactly - which is also elision on move operations.
> I'd say it's not a simplification of my examples but a completely
> different thing.
> So I guess not having move-elision on `sink` arguments can still be
> considered a `defect`.
>
Please don't use the term move-elision, this is IMO totally confusing.
- Daniel
--
---
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/.
--047d7b86f172dfb64204e6305c0d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2013=
/9/12 Vittorio Romeo <span dir=3D"ltr"><<a href=3D"mailto:vittorio.romeo=
@outlook.com" target=3D"_blank">vittorio.romeo@outlook.com</a>></span><b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">
<div><div dir=3D"ltr">That's `traditional` move/copy elision in my book=
- the typical elision done on return from functions.</div></div></blockquo=
te><div><br></div><div>Exactly - which is also elision on move operations.<=
br>
</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div dir=3D"ltr"><d=
iv>I'd say it's not a simplification of my examples but a completel=
y different thing.<br>
<div>So I guess not having move-elision on `sink` arguments can still be co=
nsidered a `defect`.<br></div></div></div></div></blockquote><div><br></div=
><div>Please don't use the term move-elision, this is IMO totally confu=
sing.<br>
<br></div><div>- Daniel<br></div><div class=3D"im">=A0<br></div></div><br><=
/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 />
--047d7b86f172dfb64204e6305c0d--
.
Author: Jonathan Wakely <cxx@kayari.org>
Date: Thu, 12 Sep 2013 08:31:19 -0700 (PDT)
Raw View
------=_Part_370_21760256.1378999879823
Content-Type: text/plain; charset=ISO-8859-1
On Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio Romeo wrote:
>
> That's `traditional` move/copy elision in my book - the typical elision
> done on return from functions.
>
Well yes, when I said move elision is allowed in C++11 I was responding to
"That means the compiler is allowed to remove moves *in the same way
compilers are allowed to remove copies*." (emphasis mine.)
And it's clearly move elision (not copy elision) if it happens for a type
that is not copyable:
struct MoveOnly {
MoveOnly() = default;
MoveOnly(MoveOnly&&) { throw 1; }
};
MoveOnly f()
{
MoveOnly mo;
return mo;
}
int main()
{
auto mo = f();
}
With my compilers this program exits normally.
--
---
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_370_21760256.1378999879823
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio=
Romeo wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div><div dir=3D"ltr">That's `traditional` move/copy elision in my book - t=
he typical elision done on return from functions.</div></div></blockquote><=
div><br>Well yes, when I said move elision is allowed in C++11 I was respon=
ding to "That means the compiler is allowed to remove moves <b>in the same=
way compilers are allowed to remove copies</b>." (emphasis mine.)<br><br>A=
nd it's clearly move elision (not copy elision) if it happens for a type th=
at is not copyable:<br></div><br>struct MoveOnly {<br> Mo=
veOnly() =3D default;<br> MoveOnly(MoveOnly&&) { =
throw 1; }<br>};<br><br>MoveOnly f()<br>{<br> MoveOnly mo=
;<br> return mo;<br>}<br><br>int main()<br>{<br> &nb=
sp; auto mo =3D f();<br>}<br><br>With my compilers this program exits=
normally.<br><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 />
------=_Part_370_21760256.1378999879823--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sat, 14 Sep 2013 11:30:13 -0700 (PDT)
Raw View
------=_Part_1677_2391304.1379183413152
Content-Type: text/plain; charset=ISO-8859-1
Hi,
I'm still catching up with the discussion on this thread. For now, I just
want to point to the original blog post that discussed the "sink helper".
blog:
http://codesynthesis.com/~boris/blog/2012/06/26/efficient-argument-passing-cxx11-part2
The original code is more complex than what I have in the
slides: http://codesynthesis.com/~boris/data/argument-passing/in.tar.gz
Thanks,
Sumant
On Thursday, September 12, 2013 8:31:19 AM UTC-7, Jonathan Wakely wrote:
>
> On Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio Romeo wrote:
>>
>> That's `traditional` move/copy elision in my book - the typical elision
>> done on return from functions.
>>
>
> Well yes, when I said move elision is allowed in C++11 I was responding to
> "That means the compiler is allowed to remove moves *in the same way
> compilers are allowed to remove copies*." (emphasis mine.)
>
> And it's clearly move elision (not copy elision) if it happens for a type
> that is not copyable:
>
> struct MoveOnly {
> MoveOnly() = default;
> MoveOnly(MoveOnly&&) { throw 1; }
> };
>
> MoveOnly f()
> {
> MoveOnly mo;
> return mo;
> }
>
> int main()
> {
> auto mo = f();
> }
>
> With my compilers this program exits normally.
>
>
--
---
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_1677_2391304.1379183413152
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi, <div><br></div><div>I'm still catching up with th=
e discussion on this thread. For now, I just want to point to the original =
blog post that discussed the "sink helper".</div><div>blog: <a href=3D=
"http://codesynthesis.com/~boris/blog/2012/06/26/efficient-argument-passing=
-cxx11-part2">http://codesynthesis.com/~boris/blog/2012/06/26/efficient-arg=
ument-passing-cxx11-part2</a></div><div>The original code is more complex t=
han what I have in the slides: http://codesynthesis.com/~boris/data/ar=
gument-passing/in.tar.gz </div><div><br></div><div>Thanks,</div><div>S=
umant<br><br>On Thursday, September 12, 2013 8:31:19 AM UTC-7, Jonathan Wak=
ely wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On =
Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio Romeo wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex">
<div><div dir=3D"ltr">That's `traditional` move/copy elision in my book - t=
he typical elision done on return from functions.</div></div></blockquote><=
div><br>Well yes, when I said move elision is allowed in C++11 I was respon=
ding to "That means the compiler is allowed to remove moves <b>in the same=
way compilers are allowed to remove copies</b>." (emphasis mine.)<br><br>A=
nd it's clearly move elision (not copy elision) if it happens for a type th=
at is not copyable:<br></div><br>struct MoveOnly {<br> Mo=
veOnly() =3D default;<br> MoveOnly(MoveOnly&&) { =
throw 1; }<br>};<br><br>MoveOnly f()<br>{<br> MoveOnly mo=
;<br> return mo;<br>}<br><br>int main()<br>{<br> &nb=
sp; auto mo =3D f();<br>}<br><br>With my compilers this program exits=
normally.<br><br></div></blockquote></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_1677_2391304.1379183413152--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sat, 14 Sep 2013 15:27:07 -0700
Raw View
--047d7b5d33d40f2ca204e65f7bd3
Content-Type: text/plain; charset=ISO-8859-1
It has the same problem I described though:
T move () const {return lv_ ? *lv_ : std::move (*rv_);}
This is functionally equivalent to pass-by-value. The rule for RVO is that
all return paths must be rvalues (not true, lv_ is an lvalue), and for NRVO
that all returns are a single local variable (neither conditional is a
local variable, and they are different). Therefore, you get a copy of T,
either copy constructed or move constructed depending on lv_. That value is
move constructed (which may be a copy construction if T has no move
constructor) into whatever code called sink::move().
As I said, I really would like to see something like this happen, but this
implementation is functionally equivalent to the pass-by-value solution.
I'm not sure if an implementation that actually works here is possible in
the current language.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Sat, Sep 14, 2013 at 11:30 AM, Sumant Tambe <sutambe@gmail.com> wrote:
> Hi,
>
> I'm still catching up with the discussion on this thread. For now, I just
> want to point to the original blog post that discussed the "sink helper".
> blog:
> http://codesynthesis.com/~boris/blog/2012/06/26/efficient-argument-passing-cxx11-part2
> The original code is more complex than what I have in the slides:
> http://codesynthesis.com/~boris/data/argument-passing/in.tar.gz
>
> Thanks,
> Sumant
>
>
> On Thursday, September 12, 2013 8:31:19 AM UTC-7, Jonathan Wakely wrote:
>>
>> On Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio Romeo wrote:
>>>
>>> That's `traditional` move/copy elision in my book - the typical elision
>>> done on return from functions.
>>>
>>
>> Well yes, when I said move elision is allowed in C++11 I was responding
>> to "That means the compiler is allowed to remove moves *in the same way
>> compilers are allowed to remove copies*." (emphasis mine.)
>>
>> And it's clearly move elision (not copy elision) if it happens for a type
>> that is not copyable:
>>
>> struct MoveOnly {
>> MoveOnly() = default;
>> MoveOnly(MoveOnly&&) { throw 1; }
>> };
>>
>> MoveOnly f()
>> {
>> MoveOnly mo;
>> return mo;
>> }
>>
>> int main()
>> {
>> auto mo = f();
>> }
>>
>> With my compilers this program exits normally.
>>
>> --
>
> ---
> 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/.
--047d7b5d33d40f2ca204e65f7bd3
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>It has the same problem I described though:</div><div=
>=A0</div><div>T move () const {return lv_ ? *lv_ : std::move (*rv_);}<br><=
/div><div>This is functionally equivalent to pass-by-value. The rule for RV=
O is that all return paths must be rvalues (not true, lv_ is an lvalue), an=
d for NRVO that all returns are a single local variable (neither conditiona=
l is a local variable, and they are different). Therefore, you get a copy o=
f T, either copy constructed or move constructed depending on lv_. That val=
ue is move constructed (which may be a copy construction if T has no move c=
onstructor) into whatever code called sink::move().</div>
<div>=A0</div><div>As I said, I really would like to see something like thi=
s happen, but this implementation is functionally equivalent to the pass-by=
-value solution. I'm not sure if an implementation that actually works =
here is possible in the current language.</div>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>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://=
stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 11:30 AM, Sumant=
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D=
"_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
<div dir=3D"ltr">Hi,=A0<div><br></div><div>I'm still catching up with t=
he discussion on this thread. For now, I just want to point to the original=
blog post that discussed the "sink helper".</div><div>blog:=A0<a=
href=3D"http://codesynthesis.com/~boris/blog/2012/06/26/efficient-argument=
-passing-cxx11-part2" target=3D"_blank">http://codesynthesis.com/~boris/blo=
g/2012/06/26/efficient-argument-passing-cxx11-part2</a></div>
<div>The original code is more complex than what I have in the slides:=A0<a=
href=3D"http://codesynthesis.com/~boris/data/argument-passing/in.tar.gz" t=
arget=3D"_blank">http://codesynthesis.com/~boris/data/argument-passing/in.t=
ar.gz</a>=A0</div>
<div><br></div><div>Thanks,</div><div>Sumant<div><div class=3D"h5"><br><br>=
On Thursday, September 12, 2013 8:31:19 AM UTC-7, Jonathan Wakely wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-le=
ft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left=
-style:solid">
<div dir=3D"ltr">On Thursday, September 12, 2013 2:28:50 PM UTC+1, Vittorio=
Romeo wrote:<blockquote class=3D"gmail_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">
<div><div dir=3D"ltr">That's `traditional` move/copy elision in my book=
- the typical elision done on return from functions.</div></div></blockquo=
te><div><br>Well yes, when I said move elision is allowed in C++11 I was re=
sponding to "That means the compiler is allowed to remove moves <b>in=
the same way compilers are allowed to remove copies</b>." (emphasis m=
ine.)<br>
<br>And it's clearly move elision (not copy elision) if it happens for =
a type that is not copyable:<br></div><br>struct MoveOnly {<br>=A0=A0=A0 Mo=
veOnly() =3D default;<br>=A0=A0=A0 MoveOnly(MoveOnly&&) { throw 1; =
}<br>};<br>
<br>MoveOnly f()<br>{<br>=A0=A0=A0 MoveOnly mo;<br>=A0=A0=A0 return mo;<br>=
}<br><br>int main()<br>{<br>=A0=A0=A0 auto mo =3D f();<br>}<br><br>With my =
compilers this program exits normally.<br><br></div></blockquote></div></di=
v></div></div><div class=3D"HOEnZb">
<div class=3D"h5">
<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>
</div></div></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 />
--047d7b5d33d40f2ca204e65f7bd3--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sat, 14 Sep 2013 19:59:27 -0700 (PDT)
Raw View
The goal is not to do better than pass-by-value-and-move approach. But to a=
llow run-time query on argument lvalue/ rvalue-ness without forcing the use=
of universal references and exponential explosion argument types when rva=
lue refs are used. I'm ready to accept a couple of extra moves in return of=
a single expressive function declaration (and implementation) which modern=
editors can help autocomplete. in<T> is not meant for constructor argument=
s because pass-by-value-and-move approach works better over there.=20
If the idea has any merit, I would prefer "in" over "sink" because argument=
s dont necessarily sink (like in unique-ptr).=20
Thanks,
Sumant
--=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/.
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sat, 14 Sep 2013 21:02:34 -0700
Raw View
--089e01161b46b0fd6b04e6642aca
Content-Type: text/plain; charset=ISO-8859-1
How does that cause exponential explosion? Pass by value every time, and
you have no overloads.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Sat, Sep 14, 2013 at 7:59 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> The goal is not to do better than pass-by-value-and-move approach. But to
> allow run-time query on argument lvalue/ rvalue-ness without forcing the
> use of universal references and exponential explosion argument types when
> rvalue refs are used. I'm ready to accept a couple of extra moves in return
> of a single expressive function declaration (and implementation) which
> modern editors can help autocomplete. in<T> is not meant for constructor
> arguments because pass-by-value-and-move approach works better over there.
>
> If the idea has any merit, I would prefer "in" over "sink" because
> arguments dont necessarily sink (like in unique-ptr).
>
> Thanks,
> Sumant
>
> --
>
> ---
> 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/.
--089e01161b46b0fd6b04e6642aca
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">How does that cause exponential explosion? Pass by value e=
very time, and you have no overloads.</div><div class=3D"gmail_extra"><br c=
lear=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://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 7:59 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D"=
_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">
The goal is not to do better than pass-by-value-and-move approach. But to a=
llow run-time query on argument lvalue/ rvalue-ness without forcing the use=
of universal references and exponential =A0explosion argument types when r=
value refs are used. I'm ready to accept a couple of extra moves in ret=
urn of a single expressive function declaration (and implementation) which =
modern editors can help autocomplete. in<T> is not meant for construc=
tor arguments because pass-by-value-and-move approach works better over the=
re.<br>
<br>
If the idea has any merit, I would prefer "in" over "sink&qu=
ot; because arguments dont necessarily sink (like in unique-ptr).<br>
<br>
Thanks,<br>
Sumant<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<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 <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
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></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 />
--089e01161b46b0fd6b04e6642aca--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sat, 14 Sep 2013 21:43:26 -0700 (PDT)
Raw View
I mean to say there are 3 options and in<T> might be the 4th.
1. Using universal refs (forces template)
2. Using rvalue refs and const lvalue refs conbination (causes exponential number of function versions)
3. Pass by value (good only with sink args)
4. Pass as std::in<T>
--
---
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/.
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sat, 14 Sep 2013 21:53:51 -0700
Raw View
--001a11c2d6a021b8b004e664e21f
Content-Type: text/plain; charset=ISO-8859-1
How is 3 different than 4? They both result in a value copy in all cases.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Sat, Sep 14, 2013 at 9:43 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> I mean to say there are 3 options and in<T> might be the 4th.
> 1. Using universal refs (forces template)
> 2. Using rvalue refs and const lvalue refs conbination (causes exponential
> number of function versions)
> 3. Pass by value (good only with sink args)
> 4. Pass as std::in<T>
>
> --
>
> ---
> 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/.
--001a11c2d6a021b8b004e664e21f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">How is 3 different than 4? They both result in a value cop=
y in all cases.</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div=
dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.o=
rg/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://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 9:43 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D"=
_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">
I mean to say there are 3 options and in<T> might be the 4th.<br>
1. Using universal refs (forces template)<br>
2. Using rvalue refs and const lvalue refs conbination (causes exponential =
number of function versions)<br>
3. Pass by value (good only with sink args)<br>
4. Pass as std::in<T><br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<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 <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
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></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 />
--001a11c2d6a021b8b004e664e21f--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sat, 14 Sep 2013 23:21:46 -0700 (PDT)
Raw View
------=_Part_340_10860185.1379226106579
Content-Type: text/plain; charset=ISO-8859-1
Billy,
Please consider the following matrix class and the test code after that:
struct matrix {
matrix () {}
matrix (matrix const&) {cout << "copy-ctor, ";}
matrix (matrix&&) {cout << "move-ctor, ";}
matrix & operator = (matrix const &) { cout << "copy-assign, "; return
*this; }
matrix & operator = (matrix &&) { cout << "move-assign, "; return *this; }
matrix& operator+= (const matrix &m) {
return *this;
}
std::vector<int> data;
};
inline matrix operator+ (in<matrix> x, in<matrix> y) {
return std::move (
x.rvalue () ? x.rget () += y :
y.rvalue () ? y.rget () += x :
matrix (x) += y);
}
matrix s1;
matrix s2;
matrix m1 (matrix() + s1); cout << endl; (1)
matrix m2 (matrix() + matrix()); cout << endl; (2)
matrix m3 (s1 + s2); cout << endl; (3)
matrix m4 (s1 + matrix()); cout << endl; (4)
The question here is how to implement the binary operator +().
Pass-by-value for operator +() ends up making two copies of the matrix
every time. in<matrix> version makes a copy only when necessary i.e., in
case #3--without directly using T&&, matrix&&, and const matrix &. Note
that this just an example and in<T> is usable beyond operator+().
Thanks,
Sumant
On Saturday, September 14, 2013 9:53:51 PM UTC-7, Billy O'Neal wrote:
>
> How is 3 different than 4? They both result in a value copy in all cases.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Sat, Sep 14, 2013 at 9:43 PM, Sumant Tambe <sut...@gmail.com<javascript:>
> > wrote:
>
>> I mean to say there are 3 options and in<T> might be the 4th.
>> 1. Using universal refs (forces template)
>> 2. Using rvalue refs and const lvalue refs conbination (causes
>> exponential number of function versions)
>> 3. Pass by value (good only with sink args)
>> 4. Pass as std::in<T>
>>
>> --
>>
>> ---
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> 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/.
------=_Part_340_10860185.1379226106579
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Billy,<div><br></div><div>Please consider the following ma=
trix class and the test code after that:</div><div><br></div><div><div><div=
>struct matrix {</div><div> matrix () {}</div><div> matrix (mat=
rix const&) {cout << "copy-ctor, ";}</div><div> matrix (mat=
rix&&) {cout << "move-ctor, ";}</div><div><div> matrix =
& operator =3D (matrix const &) { cout << "copy-assign, "; re=
turn *this; }</div><div> matrix & operator =3D (matrix &&=
) { cout << "move-assign, "; return *this; }</div></div><div><br></di=
v><div> matrix& operator+=3D (const matrix &m) {</div><div>&n=
bsp; return *this;</div><div> }</div><div> std::vector&l=
t;int> data;<br></div><div>};</div></div><div><br></div><div>inline matr=
ix operator+ (in<matrix> x, in<matrix> y) {</div><div> re=
turn std::move (</div><div> x.rvalue () ? x.rget () +=3D y :</=
div><div> y.rvalue () ? y.rget () +=3D x :</div><div> &n=
bsp; matrix (x) +=3D y);</div><div>}</div></div><div><br></div><div><div>&n=
bsp; matrix s1;</div><div> matrix s2;</div><div> =
matrix m1 (matrix() + s1); cout << =
endl; (1)</div><div> matrix m2 (matrix() + matrix()); co=
ut << endl; (2)</div><div> matrix m3 (s1 + s2); &=
nbsp; cout << endl; (3) </div>=
<div> matrix m4 (s1 + matrix()); co=
ut << endl; (4)</div><div><br></div><div><div>The question here is ho=
w to implement the binary operator +(). Pass-by-value for operator +() ends=
up making two copies of the matrix every time. in<matrix> version ma=
kes a copy only when necessary i.e., in case #3--without directly using T&a=
mp;&, matrix&&, and const matrix &. Note that this just an =
example and in<T> is usable beyond operator+().</div></div></div><div=
><br></div><div>Thanks,</div><div>Sumant</div><div><br></div><div>On Saturd=
ay, September 14, 2013 9:53:51 PM UTC-7, Billy O'Neal wrote:<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">How is 3 different than 4? T=
hey both result in a value copy in all cases.</div><div><br clear=3D"all"><=
div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbuck=
et.org/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</a></d=
iv>
<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/<wbr>users/82320/billy-oneal</a></div><di=
v>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 9:43 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-o=
bfuscated-mailto=3D"WT6Gem3YSXUJ">sut...@gmail.com</a>></span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
I mean to say there are 3 options and in<T> might be the 4th.<br>
1. Using universal refs (forces template)<br>
2. Using rvalue refs and const lvalue refs conbination (causes exponential =
number of function versions)<br>
3. Pass by value (good only with sink args)<br>
4. Pass as std::in<T><br>
<div><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 <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
WT6Gem3YSXUJ">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"WT6Gem3YSXUJ">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></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_340_10860185.1379226106579--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sat, 14 Sep 2013 23:23:23 -0700 (PDT)
Raw View
------=_Part_2316_5465836.1379226203916
Content-Type: text/plain; charset=ISO-8859-1
Correction: Pass-by-value approach makes two copies when both parameters
are lvalues. Not "everytime".
On Saturday, September 14, 2013 11:21:46 PM UTC-7, Sumant Tambe wrote:
>
> Billy,
>
> Please consider the following matrix class and the test code after that:
>
> struct matrix {
> matrix () {}
> matrix (matrix const&) {cout << "copy-ctor, ";}
> matrix (matrix&&) {cout << "move-ctor, ";}
> matrix & operator = (matrix const &) { cout << "copy-assign, "; return
> *this; }
> matrix & operator = (matrix &&) { cout << "move-assign, "; return *this;
> }
>
> matrix& operator+= (const matrix &m) {
> return *this;
> }
> std::vector<int> data;
> };
>
> inline matrix operator+ (in<matrix> x, in<matrix> y) {
> return std::move (
> x.rvalue () ? x.rget () += y :
> y.rvalue () ? y.rget () += x :
> matrix (x) += y);
> }
>
> matrix s1;
> matrix s2;
> matrix m1 (matrix() + s1); cout << endl; (1)
> matrix m2 (matrix() + matrix()); cout << endl; (2)
> matrix m3 (s1 + s2); cout << endl; (3)
> matrix m4 (s1 + matrix()); cout << endl; (4)
>
> The question here is how to implement the binary operator +().
> Pass-by-value for operator +() ends up making two copies of the matrix
> every time. in<matrix> version makes a copy only when necessary i.e., in
> case #3--without directly using T&&, matrix&&, and const matrix &. Note
> that this just an example and in<T> is usable beyond operator+().
>
> Thanks,
> Sumant
>
> On Saturday, September 14, 2013 9:53:51 PM UTC-7, Billy O'Neal wrote:
>>
>> How is 3 different than 4? They both result in a value copy in all cases.
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/users/82320/billy-oneal
>> Malware Response Instructor - BleepingComputer.com
>>
>>
>> On Sat, Sep 14, 2013 at 9:43 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>
>>> I mean to say there are 3 options and in<T> might be the 4th.
>>> 1. Using universal refs (forces template)
>>> 2. Using rvalue refs and const lvalue refs conbination (causes
>>> exponential number of function versions)
>>> 3. Pass by value (good only with sink args)
>>> 4. Pass as std::in<T>
>>>
>>> --
>>>
>>> ---
>>> 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-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@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/.
------=_Part_2316_5465836.1379226203916
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Correction: Pass-by-value approach makes two copies when b=
oth parameters are lvalues. Not "everytime". <br><br>On Saturday, Sept=
ember 14, 2013 11:21:46 PM UTC-7, Sumant Tambe wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr">Billy,<div><br></div><div>Please co=
nsider the following matrix class and the test code after that:</div><div><=
br></div><div><div><div>struct matrix {</div><div> matrix () {}</div>=
<div> matrix (matrix const&) {cout << "copy-ctor, ";}</div>=
<div> matrix (matrix&&) {cout << "move-ctor, ";}</div><=
div><div> matrix & operator =3D (matrix const &) { cout <&=
lt; "copy-assign, "; return *this; }</div><div> matrix & operator=
=3D (matrix &&) { cout << "move-assign, "; return *this; }</=
div></div><div><br></div><div> matrix& operator+=3D (const matrix=
&m) {</div><div> return *this;</div><div> }</div><d=
iv> std::vector<int> data;<br></div><div>};</div></div><div><br=
></div><div>inline matrix operator+ (in<matrix> x, in<matrix> y=
) {</div><div> return std::move (</div><div> x.rvalue ()=
? x.rget () +=3D y :</div><div> y.rvalue () ? y.rget () +=3D =
x :</div><div> matrix (x) +=3D y);</div><div>}</div></div><div=
><br></div><div><div> matrix s1;</div><div> matri=
x s2;</div><div> matrix m1 (matrix() + s1); &nbs=
p; cout << endl; (1)</div><div> matrix m2 (matrix(=
) + matrix()); cout << endl; (2)</div><div> matrix=
m3 (s1 + s2); cout <<=
; endl; (3) </div><div> matrix m4 (s1 + matrix()); =
cout << endl; (4)</div><div><br></div><div><div>=
The question here is how to implement the binary operator +(). Pass-by-valu=
e for operator +() ends up making two copies of the matrix every time. in&l=
t;matrix> version makes a copy only when necessary i.e., in case #3--wit=
hout directly using T&&, matrix&&, and const matrix &. =
Note that this just an example and in<T> is usable beyond operator+()=
..</div></div></div><div><br></div><div>Thanks,</div><div>Sumant</div><div><=
br></div><div>On Saturday, September 14, 2013 9:53:51 PM UTC-7, Billy O'Nea=
l wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">How is 3 d=
ifferent than 4? They both result in a value copy in all cases.</div><div><=
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://stackoverflow.com/<wbr>users/82320/billy-oneal</a></div><di=
v>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 9:43 PM, Sumant =
Tambe <span dir=3D"ltr"><<a>sut...@gmail.com</a>></span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">
I mean to say there are 3 options and in<T> might be the 4th.<br>
1. Using universal refs (forces template)<br>
2. Using rvalue refs and const lvalue refs conbination (causes exponential =
number of function versions)<br>
3. Pass by value (good only with sink args)<br>
4. Pass as std::in<T><br>
<div><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 <a>std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></div></div></blockquote></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_2316_5465836.1379226203916--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Sun, 15 Sep 2013 00:17:16 -0700
Raw View
--001a11c2e81c0b7f0204e666e337
Content-Type: text/plain; charset=ISO-8859-1
Ok, that's interesting.
Let's consider 3 possible implementations of operator+. First, the C++03
way:
// Example 1
inline matrix operator+ (matrix const& x, matrix const& y) {
matrix result(x);
result += y;
return result;
}
This always makes exactly one copy, the construction of result. NRVO
removes the copy construction of the return value.
An alternate formulation in the land of move-semantics which is still
compliant would be this one:
// Example 2
inline matrix operator+ (matrix result, matrix const& y) {
result += y;
return result;
}
which allows replacing the single copy with a move, meaning this always
takes a copy or a move, depending on the first argument to operator+. If
the left side is an lvalue, then you get a copy; if it is an rvalue, you
get a move.
Now let's look at your sink solution:
// Example 3
inline matrix operator+ (in<matrix> x, in<matrix> y) {
return std::move (
x.rvalue () ? x.rget () += y :
y.rvalue () ? y.rget () += x :
matrix (x) += y);
}
This solution does allow choosing of which side to "steal" from at run
time. Let's go through each combination of arguments:
1. Two r value inputs. This causes one move construction in order to
construct the return value -- no better than Example 2 above. (The result
of a call to std::move() this way is not eligible for RVO/NRVO) It also
adds 2 branches not present in example 2, and adds the cost of passing 2
bool sized values as arguments (or more, depending on alignment
requirements or whatever).
2. Two l value inputs. This causes one copy construction, (temporary
matrix(x)), plus a move to construct the return value of operator+. One
extra move not present in example 1 or 2, not counting additional overhead
from passing the bools.
3. lvalue on the left, rvalue on the right. In this case, you get one move
construction for the return value of operator+. This is an improvement,
because example 2 above can't detect that the argument on the right is an
rvalue.
4. rvalue on the left, lvalue on the right. In this case, you get one move
construction again, but example 2 above already had this property. You lose
the same overhead of the branches and bools, of course.
So, the same in 2 cases, slightly better in 1 case, slightly worse in 1
case. Don't think this is really worth it. My advice would be to just write
example 2 above, and if you profile and find this to be on the hot path and
have cases where rvalue references are on the right, then use perfect
forwarding or overloads.
I worry that because we have move semantics now, people are going to start
getting hammer-nail syndrome over them. Yes, they do help perf in some
cases, but the complexity they add probably isn't all that important in
most places. Listen to your profiler, and add that complexity where it is
warranted.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Sat, Sep 14, 2013 at 11:23 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> Correction: Pass-by-value approach makes two copies when both parameters
> are lvalues. Not "everytime".
>
>
> On Saturday, September 14, 2013 11:21:46 PM UTC-7, Sumant Tambe wrote:
>>
>> Billy,
>>
>> Please consider the following matrix class and the test code after that:
>>
>> struct matrix {
>> matrix () {}
>> matrix (matrix const&) {cout << "copy-ctor, ";}
>> matrix (matrix&&) {cout << "move-ctor, ";}
>> matrix & operator = (matrix const &) { cout << "copy-assign, "; return
>> *this; }
>> matrix & operator = (matrix &&) { cout << "move-assign, "; return
>> *this; }
>>
>> matrix& operator+= (const matrix &m) {
>> return *this;
>> }
>> std::vector<int> data;
>> };
>>
>> inline matrix operator+ (in<matrix> x, in<matrix> y) {
>> return std::move (
>> x.rvalue () ? x.rget () += y :
>> y.rvalue () ? y.rget () += x :
>> matrix (x) += y);
>> }
>>
>> matrix s1;
>> matrix s2;
>> matrix m1 (matrix() + s1); cout << endl; (1)
>> matrix m2 (matrix() + matrix()); cout << endl; (2)
>> matrix m3 (s1 + s2); cout << endl; (3)
>> matrix m4 (s1 + matrix()); cout << endl; (4)
>>
>> The question here is how to implement the binary operator +().
>> Pass-by-value for operator +() ends up making two copies of the matrix
>> every time. in<matrix> version makes a copy only when necessary i.e., in
>> case #3--without directly using T&&, matrix&&, and const matrix &. Note
>> that this just an example and in<T> is usable beyond operator+().
>>
>> Thanks,
>> Sumant
>>
>> On Saturday, September 14, 2013 9:53:51 PM UTC-7, Billy O'Neal wrote:
>>>
>>> How is 3 different than 4? They both result in a value copy in all cases.
>>>
>>> Billy O'Neal
>>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>>> Malware Response Instructor - BleepingComputer.com
>>>
>>>
>>> On Sat, Sep 14, 2013 at 9:43 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>>
>>>> I mean to say there are 3 options and in<T> might be the 4th.
>>>> 1. Using universal refs (forces template)
>>>> 2. Using rvalue refs and const lvalue refs conbination (causes
>>>> exponential number of function versions)
>>>> 3. Pass by value (good only with sink args)
>>>> 4. Pass as std::in<T>
>>>>
>>>> --
>>>>
>>>> ---
>>>> 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-proposal...@isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>> Visit this group at http://groups.google.com/a/**isocpp.org/group/std-*
>>>> *proposals/<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/.
>
--
---
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/.
--001a11c2e81c0b7f0204e666e337
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Ok, that's interesting.</div><div>=A0</div><div>L=
et's consider 3 possible implementations of operator+. First, the C++03=
way:</div><div>=A0</div><div>// Example 1</div><div>inline matrix operator=
+ (matrix const& x, matrix const& y) {<br>
=A0 matrix result(x);<br>=A0 result +=3D y;<br>=A0 return result;<br>}</div=
><div>=A0</div><div>This always makes exactly one copy, the construction of=
result. NRVO removes the copy construction of the return value.</div><div>=
=A0</div>
<div>An alternate formulation in the land of move-semantics which is still =
compliant would be this one:</div><div>=A0</div><div>// Example 2</div><div=
>inline matrix operator+ (matrix result, matrix const& y) {<br>=A0 resu=
lt +=3D y;<br>
=A0 return result;<br>}</div><div>=A0</div><div>which allows replacing the =
single copy with a move, meaning this always takes a copy or a move, depend=
ing on the first argument to operator+. If the left side is an lvalue, then=
you get a copy; if it is an rvalue, you get a move.</div>
<div>=A0</div><div>Now let's look at your sink solution:</div><div>=A0<=
/div><div>// Example 3</div><div>inline matrix operator+ (in<matrix> =
x, in<matrix> y) {<br>=A0 return std::move (<br>=A0=A0=A0 x.rvalue ()=
? x.rget () +=3D y :<br>
=A0=A0=A0 y.rvalue () ? y.rget () +=3D x :<br>=A0=A0=A0 matrix (x) +=3D y);=
<br>}</div><div>=A0</div><div>This solution does allow choosing of which si=
de to "steal" from at run time. Let's go through each combina=
tion of arguments:</div>
<div>1. Two r value inputs. This causes one move construction in order to c=
onstruct the return value -- no better than Example 2 above. (The result of=
a call to std::move() this way is not eligible for RVO/NRVO)=A0It also add=
s 2 branches not present in example 2, and adds the cost of passing 2 bool =
sized values as arguments (or more, depending on alignment requirements or =
whatever).</div>
<div>2. Two l value inputs. This causes one copy construction, (temporary m=
atrix(x)), plus a move to construct the return value of operator+. One extr=
a move not present in example 1 or 2, not counting additional overhead from=
passing the bools.</div>
<div>3. lvalue on the left, rvalue on the right. In this case, you get one =
move construction for the return value of operator+. This is an improvement=
, because example 2 above can't detect that the argument on the right i=
s an rvalue.</div>
<div>4. rvalue on the left, lvalue on the right. In this case, you get one =
move construction again, but example 2 above already had this property. You=
lose the same overhead of the branches and bools, of course.</div><div>
=A0</div><div>So, the same in 2 cases, slightly better in 1 case, slightly =
worse in 1 case. Don't think this is really worth it. My advice would b=
e to just write example 2 above, and if you profile and find this to be on =
the hot path and have cases where rvalue references are on the right, then =
use perfect forwarding or overloads.</div>
<div>=A0</div><div>I worry that because we have move semantics now, people =
are going to start getting hammer-nail syndrome over them. Yes, they do hel=
p perf in some cases, but the complexity they add probably isn't all th=
at important in most places. Listen to your profiler, and add that complexi=
ty where it is warranted.</div>
<div>=A0</div></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div =
dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.or=
g/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</a></div><d=
iv><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_=
blank">http://stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 11:23 PM, Sumant=
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D=
"_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
<div dir=3D"ltr">Correction: Pass-by-value approach makes two copies when b=
oth parameters are lvalues. Not "everytime".=A0<div><div class=3D=
"h5"><br><br>On Saturday, September 14, 2013 11:21:46 PM UTC-7, Sumant Tamb=
e wrote:<blockquote class=3D"gmail_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">
<div dir=3D"ltr">Billy,<div><br></div><div>Please consider the following ma=
trix class and the test code after that:</div><div><br></div><div><div><div=
>struct matrix {</div><div>=A0 matrix () {}</div><div>=A0 matrix (matrix co=
nst&) {cout << "copy-ctor, ";}</div>
<div>=A0 matrix (matrix&&) {cout << "move-ctor, ";}=
</div><div><div>=A0 matrix & operator =3D (matrix const &) { cout &=
lt;< "copy-assign, "; return *this; }</div><div>=A0 matrix &am=
p; operator =3D (matrix &&) { cout << "move-assign, &quo=
t;; return *this; }</div>
</div><div><br></div><div>=A0 matrix& operator+=3D (const matrix &m=
) {</div><div>=A0 =A0 return *this;</div><div>=A0 }</div><div>=A0 std::vect=
or<int> data;<br></div><div>};</div></div><div><br></div><div>inline =
matrix operator+ (in<matrix> x, in<matrix> y) {</div>
<div>=A0 return std::move (</div><div>=A0 =A0 x.rvalue () ? x.rget () +=3D =
y :</div><div>=A0 =A0 y.rvalue () ? y.rget () +=3D x :</div><div>=A0 =A0 ma=
trix (x) +=3D y);</div><div>}</div></div><div><br></div><div><div>=A0 =A0 m=
atrix s1;</div><div>
=A0 =A0 matrix s2;</div><div>=A0 =A0 matrix m1 (matrix() + s1); =A0 =A0 =A0=
=A0cout << endl; (1)</div><div>=A0 =A0 matrix m2 (matrix() + matrix(=
)); =A0cout << endl; (2)</div><div>=A0 =A0 matrix m3 (s1 + s2); =A0 =
=A0 =A0 =A0 =A0 =A0 =A0cout << endl; (3)=A0</div>
<div>=A0 =A0 matrix m4 (s1 + matrix()); =A0 =A0 =A0 =A0cout << endl; =
(4)</div><div><br></div><div><div>The question here is how to implement the=
binary operator +(). Pass-by-value for operator +() ends up making two cop=
ies of the matrix every time. in<matrix> version makes a copy only wh=
en necessary i.e., in case #3--without directly using T&&, matrix&a=
mp;&, and const matrix &. Note that this just an example and in<=
T> is usable beyond operator+().</div>
</div></div><div><br></div><div>Thanks,</div><div>Sumant</div><div><br></di=
v><div>On Saturday, September 14, 2013 9:53:51 PM UTC-7, Billy O'Neal w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;pa=
dding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;bor=
der-left-style:solid">
<div dir=3D"ltr">How is 3 different than 4? They both result in a value cop=
y in all cases.</div><div><br clear=3D"all"><div><div dir=3D"ltr"><div>Bill=
y 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://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div><=
div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sat, Sep 14, 2013 at 9:43 PM, Sumant =
Tambe <span dir=3D"ltr"><<a>sut...@gmail.com</a>></span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-l=
eft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-lef=
t-style:solid">
I mean to say there are 3 options and in<T> might be the 4th.<br>
1. Using universal refs (forces template)<br>
2. Using rvalue refs and const lvalue refs conbination (causes exponential =
number of function versions)<br>
3. Pass by value (good only with sink args)<br>
4. Pass as std::in<T><br>
<div><div><br>
--<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 <a>std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@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/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></div></div></blockquote></div></div></div><div class=3D"HOEnZ=
b"><div class=3D"h5">
<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>
</div></div></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 />
--001a11c2e81c0b7f0204e666e337--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Sun, 15 Sep 2013 16:48:10 -0700 (PDT)
Raw View
------=_Part_507_3337728.1379288890687
Content-Type: text/plain; charset=ISO-8859-1
Thanks for the detailed analysis. I agree that in<T> is slightly better in
some cases and slightly inferior in others. I ran a benchmark and saw about
1-2% improvement in performance when using in<T> as opposed to the example
#2 you proposed. Each run of the benchmark executed all 4 versions
(lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of binary
operator+ with equal probability (rand() % 4).
1 to 2 % performance gain may or may not be "worth" it. People should use
their judgement. However, story does not end here.
Binary operator +() provides only one opportunity for in<T> to save a copy.
I.e., when the right hand side object is an rvalue. The in<T> idiom shines
the most when there are more opportunities to detect rvalues and to exploit
them at run-time. So here is a small function to add scalars to a list of
matrices.
std::vector<matrix>
add_scalar(std::initializer_list<in<matrix>> matrices,
std::initializer_list<int> scalars)
{
if(matrices.size() != scalars.size())
throw 0;
std::vector<matrix> result;
result.reserve(matrices.size());
auto si = begin(scalars);
for(const in<matrix> & m : matrices)
{
if(m.rvalue()) {
cout << "rvalue matrix\n";
result.push_back(std::move(m.rget() += *si));
}
else {
cout << "lvalue matrix\n";
result.push_back(std::move(matrix(m) += *si));
}
}
return result;
}
And I call it like this:
matrix s1, s2, s3, s4;
add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
I tested this code on g++ 4.9 and clang 3.3.
In each use, this function gives finite but unknown number of opportunities
to exploit move-semantics. I'm not sure if such a function can be easily
implemented using universal references. Variadic templates come to mind but
two lists of parameters probably requires separate grouping. I guess it
could be done using std::tuple and two variadic parameter packs of
universal references. But std::make_tuple is not as pretty as
std::initializer_list.
Surprisingly, in<T> works nicely with initializer_list<T>. Initilizer_list
does not appear to retain rvalue/lvalue-ness of the original parameter
because initializer_list iterator is a pointer to consts. In<T>, however,
allows the rvalue/lvalue knowledge of the original parameter pass through
the initializer_list--here is the best part--without subverting
const-correctness. All member functions in in<T> are const.
Thoughts?
Sumant
--
---
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_507_3337728.1379288890687
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4). =
<br></div><div><br></div><div>1 to 2 % performance gain may or may not be "=
worth" it. People should use their judgement. However, story does not end h=
ere.</div><div><br></div><div>Binary operator +() provides only one opportu=
nity for in<T> to save a copy. I.e., when the right hand side o=
bject is an rvalue. The in<T> idiom shines the most when there are mo=
re opportunities to detect rvalues and to exploit them at run-time. So here=
is a small function to add scalars to a list of matrices. </div><div>=
<br></div><div><div>std::vector<matrix></div><div>add_scalar(std::ini=
tializer_list<in<matrix>> matrices,</div><div> &nb=
sp; std::initializer_list<int> scalars)</div><div=
>{</div><div> if(matrices.size() !=3D scalars.size())</div><div> =
; throw 0;</div><div><br></div><div> std::vector<matrix>=
result;</div><div> result.reserve(matrices.size());</div><div> =
</div><div> auto si =3D begin(scalars);</div><div> for(co=
nst in<matrix> & m : matrices)</div><div> {</div><div> =
; if(m.rvalue()) {</div><div> cout =
<< "rvalue matrix\n";</div><div> result.pu=
sh_back(std::move(m.rget() +=3D *si));</div><div> }</div=
><div> else {</div><div> cout=
<< "lvalue matrix\n";</div><div> result.p=
ush_back(std::move(matrix(m) +=3D *si));</div><div> }</d=
iv><div> }</div><div><br></div><div> return result;</div><div>}=
</div><div><br></div><div>And I call it like this:</div><div><div><br></div=
><div>matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4=
}, { 3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g+=
+ 4.9 and clang 3.3.</div><div><br></div><div>In each use, this function gi=
ves finite but unknown number of opportunities to exploit move-semantics. I=
'm not sure if such a function can be easily implemented using universal re=
ferences. Variadic templates come to mind but two lists of parameters proba=
bly requires separate grouping. I guess it could be done using std::tuple a=
nd two variadic parameter packs of universal references. But std::make_tupl=
e is not as pretty as std::initializer_list.</div><div><br></div><div>Surpr=
isingly, in<T> works nicely with initializer_list<T>. Initilize=
r_list does not appear to retain rvalue/lvalue-ness of the original paramet=
er because initializer_list iterator is a pointer to consts. In<T>, h=
owever, allows the rvalue/lvalue knowledge of the original parameter pass t=
hrough the initializer_list--here is the best part--without subverting cons=
t-correctness. All member functions in in<T> are const. </div><=
div><br></div><div>Thoughts?</div><div><br></div><div>Sumant</div><br></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_507_3337728.1379288890687--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Mon, 16 Sep 2013 03:11:41 -0700 (PDT)
Raw View
------=_Part_1644_20488186.1379326302038
Content-Type: text/plain; charset=ISO-8859-1
My take on this would be that what we are looking for is a new type of
template parameter which only allows the "reference level" to vary, but not
the actual parameter base type, i.e. a universal reference to a specific
type. Using such a mechanism you only need to write one function, and the
compiler generates the optimal code for each call site depending on its
combination of rvalues and lvalues. I don't have a good idea about the
syntax, so in the example below I use ++ as a place holder.
matrix operator+(matrix++ x, matrix++ b)
{
matrix ret(x);
ret += y;
return ret;
}
I don't think this is a good syntax, as it is a template without the
leading template<> introducer, but maybe it could be food for thought.
The in<> approach has the definite drawback that there are tests being done
at runtime in a function implementation which is intended to have optimum
speed. That does not ring true to me. The perfect forwarding approach is
very wordy considering that you'd want to enable_if out all other base
types, especially for a free function like operator+.
An addition to the constraints idea where a class name used as a
constraints name inside the template introducer restricts arguments to that
class would have been nice, but clashes with non-typename template
parameters of course:
template<matrix&& T1, matrix&& T2> matrix operator+(T1 x, T2 y)
{
...
}
Also still pretty wordy. Creating a constexpr function Matrix that
restricts the type to matrix would be possible with the constraints idea
but I don't know if constraints will allow you to add a && after Matrix
like I did above.
--
---
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_1644_20488186.1379326302038
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>My take on this would be that what we are looking for=
is a new type of template parameter which only allows the "reference level=
" to vary, but not the actual parameter base type, i.e. a universal referen=
ce to a specific type. Using such a mechanism you only need to write one fu=
nction, and the compiler generates the optimal code for each call site depe=
nding on its combination of rvalues and lvalues. I don't have a good idea a=
bout the syntax, so in the example below I use ++ as a place holder.<br></d=
iv><div><br></div><div>matrix operator+(matrix++ x, matrix++ b)</div><div>{=
</div><div> matrix ret(x);</div><div> ret +=3D y;=
</div><div> return ret;</div><div>}</div><div><br></div><div>I=
don't think this is a good syntax, as it is a template without the leading=
template<> introducer, but maybe it could be food for thought. =
</div><div><br></div><div>The in<> approach has the definite drawback=
that there are tests being done at runtime in a function implementation wh=
ich is intended to have optimum speed. That does not ring true to me. The p=
erfect forwarding approach is very wordy considering that you'd want to ena=
ble_if out all other base types, especially for a free function like operat=
or+.</div><div><br></div><div>An addition to the constraints idea where a c=
lass name used as a constraints name inside the template introducer restric=
ts arguments to that class would have been nice, but clashes with non-typen=
ame template parameters of course:</div><div><br></div><div>template<mat=
rix&& T1, matrix&& T2> matrix operator+(T1 x, T2 y)</div=
><div>{</div><div> ...</div><div>}<br><br>Also still pretty wor=
dy. Creating a constexpr function Matrix that restricts the type to matrix =
would be possible with the constraints idea but I don't know if constraints=
will allow you to add a && after Matrix like I did above.<br><br><=
/div><div><br></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_1644_20488186.1379326302038--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Mon, 16 Sep 2013 03:20:37 -0700 (PDT)
Raw View
------=_Part_134_17110196.1379326837308
Content-Type: text/plain; charset=ISO-8859-1
Indeed, I think this is not a problem that can be solved with the current
language features. But it is still a problem that has to be solved.
In my opinion, the best course of action is having some syntax, that, when
applied to arguments, makes the compiler generate the 2^n combinations of
const& and &&.
Instead of introducing new keywords/symbols, why not use *std::sink *as a
special identifier, similarly to std::initializer_list?
void singleSinkFunc(std::sink<ExpensiveType> a) { doSomething(a); }
// v--- TRANSLATES TO ---v
void singleSinkFunc(ExpensiveType&& a) { doSomething(std::move(a)); }
void singleSinkFunc(const ExpensiveType& a) { doSomething(a); }
void doubleSinkFunc(std::sink<ExpensiveType> a, std::sink<ExpensiveType> b)
{ doSomething(a, b); }
// v--- TRANSLATES TO ---v
void doubleSinkFunc(ExpensiveType&& a, ExpensiveType&& b) {doSomething
(std::move(a), std::move(b)); }
void doubleSinkFunc(const ExpensiveType& a, ExpensiveType&& b) {doSomething
(a, std::move(b)); }
void doubleSinkFunc(ExpensiveType&& a, const ExpensiveType& b) {doSomething
(std::move(a), b); }
void doubleSinkFunc(const ExpensiveType& a, const ExpensiveType& b) {doSomething
(a, b); }
Alternative ideas for syntax:
void sinkFunc(std::in<ExpensiveType> a);
void sinkFunc(>ExpensiveType< a);
void sinkFunc(ExpensiveType<< a);
void sinkFunc(ExpensiveType sink a);
void sinkFunc(sink ExpensiveType a);
void sinkFunc(ExpensiveType in a);
void sinkFunc(in ExpensiveType a);
--
---
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_134_17110196.1379326837308
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Indeed, I think this is not a problem that can be solved w=
ith the current language features. But it is still a problem that has to be=
solved.<br>In my opinion, the best course of action is having some syntax,=
that, when applied to arguments, makes the compiler generate the 2^n combi=
nations of const& and &&.<br><br>Instead of introducing new key=
words/symbols, why not use <b>std::sink </b>as a special identifier, simila=
rly to std::initializer_list?<br><br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span>=
<font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> singleSinkFunc</span></font><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">sink<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><fo=
nt color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><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"> doSomething</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> <br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
v--- TRANSLATES TO ---v</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br><br></span></font><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">void</span><font color=3D"#000000"><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> singleSinkFunc</span></font><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">ExpensiveType</span><font color=3D"=
#666600"><span style=3D"color: #660;" class=3D"styled-by-prettify">&&am=
p;</span></font><font color=3D"#000000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> doSomething</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">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">move</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a</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"style=
d-by-prettify"><br></span></font><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">void</span><font color=3D"#000000"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> singleSinkFunc</span></font><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><font color=3D"#0000=
00"><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span></font><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</span>=
<font color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&</span></font><font color=3D"#000000"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> d=
oSomething</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">}</span></font></div></code></div><=
br><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"><font color=3D"#660066"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> doubleSinkFunc</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"styled-by-prettify"><</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">ExpensiveType</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" 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">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">sink</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">ExpensiveType</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> doSomething</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// v--- TRANSLATES TO ---v</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> doubleSinkFunc</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">ExpensiveType</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><font color=3D"#000000"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">ExpensiveType</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> b</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: #0=
00;" class=3D"styled-by-prettify"> doSomething</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</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: #000;" class=3D"styled-b=
y-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">move</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">b</span><span style=3D"color: #660;" class=3D"sty=
led-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></sp=
an></font><span style=3D"color: #008;" class=3D"styled-by-prettify">void</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> doubleSinkFu=
nc</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<font color=3D"#000000"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span></font><span style=3D"color: #606;" class=3D"styled-by-prettify">=
ExpensiveType</span><font color=3D"#666600"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&</span></font><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><font color=3D"#000000"><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">ExpensiveType</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">&&</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> b</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;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> doSomething</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">a</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">move</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">b</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"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span></font><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> doubleSinkFunc</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Exp=
ensiveType</span><font color=3D"#666600"><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&</span></font><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><font color=3D"#000000"><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span></font><font color=3D"#000000"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span></font><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">ExpensiveType</span><font color=3D"=
#666600"><span style=3D"color: #660;" class=3D"styled-by-prettify">&</s=
pan></font><font color=3D"#000000"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> doSomething</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">move</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
></font><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> doubleSinkFunc=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><f=
ont color=3D"#000000"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span></font><span style=3D"color: #606;" class=3D"styled-by-prettify">Ex=
pensiveType</span><font color=3D"#666600"><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&</span></font><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><font color=3D"#000000"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span></font><font color=3D"#000000"><span =
style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span></font><span style=
=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</span><font co=
lor=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;</span></font><font color=3D"#000000"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> b</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"> doSomethi=
ng</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> b</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"style=
d-by-prettify">}</span></font><font color=3D"#000000"><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span></font></div></code></div><=
br><br><br>Alternative ideas for syntax:<div><br></div><div><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px soli=
d rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><font color=3D"#660066"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> sinkFunc</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;" class=3D"styled-by-prett=
ify">in</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Expensive=
Type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> sinkFunc</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><font color=3D"#000000"><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">></span></font><=
span style=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> sinkFunc</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">ExpensiveType</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><<</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> a</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: #008;" class=3D"styled-by-prettify">void=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> sinkFunc<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</span>=
<font color=3D"#666600"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> sink</span></font><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> sinkFunc</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: rgb(0, 0, 0); font-family: Arial, Helvetica, sans-serif; font-si=
ze: 13px;"><span style=3D"color: #000;" class=3D"styled-by-prettify">sink <=
/span></span><span style=3D"color: #606;" class=3D"styled-by-prettify">Expe=
nsiveType</span><font color=3D"#666600" style=3D"font-family: Arial, Helvet=
ica, sans-serif; font-size: 13px;"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span></font><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">a</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> sinkFunc</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">ExpensiveType</span><fo=
nt color=3D"#666600"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">in</s=
pan></font><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</sp=
an><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: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> sinkFunc</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"font-size: 1=
3px; font-family: Arial, Helvetica, sans-serif;"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">in</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span></span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">ExpensiveType</span><font color=3D"#666600" style=
=3D"font-size: 13px; font-family: Arial, Helvetica, sans-serif;"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span></font><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span></div></code></div><br><br><br><br=
></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_134_17110196.1379326837308--
.
Author: Alex B <devalexb@gmail.com>
Date: Mon, 16 Sep 2013 08:07:31 -0700 (PDT)
Raw View
------=_Part_4735_2553645.1379344051381
Content-Type: text/plain; charset=ISO-8859-1
How do you get a function pointer to one of the four specialization of
doubleSinkFunc?
Idea of a terse notation sounds nice (sink, in, ...), but if it is a
template, there must at least be a way to declare it using the "template"
keyword, so that we could mark it explicitly that it needs to be
parameterized. And then we could get a pointer to the function taking
"const &" by specifying the parameter with a syntax
like "doubleSinkFunc<const &>". After all, it *is* a template, so we should
be able to mark it and deal with it explicitly.
On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wrote:
> Indeed, I think this is not a problem that can be solved with the current
> language features. But it is still a problem that has to be solved.
> In my opinion, the best course of action is having some syntax, that, when
> applied to arguments, makes the compiler generate the 2^n combinations of
> const& and &&.
>
> Instead of introducing new keywords/symbols, why not use *std::sink *as a
> special identifier, similarly to std::initializer_list?
>
> void singleSinkFunc(std::sink<ExpensiveType> a) { doSomething(a); }
> // v--- TRANSLATES TO ---v
>
> void singleSinkFunc(ExpensiveType&& a) { doSomething(std::move(a)); }
> void singleSinkFunc(const ExpensiveType& a) { doSomething(a); }
>
> void doubleSinkFunc(std::sink<ExpensiveType> a, std::sink<ExpensiveType> b
> ) { doSomething(a, b); }
> // v--- TRANSLATES TO ---v
>
> void doubleSinkFunc(ExpensiveType&& a, ExpensiveType&& b) {doSomething
> (std::move(a), std::move(b)); }
> void doubleSinkFunc(const ExpensiveType& a, ExpensiveType&& b) {doSomething
> (a, std::move(b)); }
> void doubleSinkFunc(ExpensiveType&& a, const ExpensiveType& b) {doSomething
> (std::move(a), b); }
> void doubleSinkFunc(const ExpensiveType& a, const ExpensiveType& b) {doSomething
> (a, b); }
>
>
>
> Alternative ideas for syntax:
>
> void sinkFunc(std::in<ExpensiveType> a);
> void sinkFunc(>ExpensiveType< a);
> void sinkFunc(ExpensiveType<< a);
> void sinkFunc(ExpensiveType sink a);
> void sinkFunc(sink ExpensiveType a);
> void sinkFunc(ExpensiveType in a);
> void sinkFunc(in ExpensiveType a);
>
>
>
>
>
--
---
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_4735_2553645.1379344051381
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>How do you get a function pointer to one of the four =
specialization of doubleSinkFunc?</div><div> </div><div>Idea of a ters=
e notation sounds nice (sink, in, ...), but if it is a template, there must=
at least be a way to declare it using the "template" keyword, so that we c=
ould mark it explicitly that it needs to be parameterized. And then we coul=
d get a pointer to the function taking "const &" by specifying the=
parameter with a syntax like "doubleSinkFunc<const &>". Aft=
er all, it <em>is</em> a template, so we should be able to mark it and deal=
with it explicitly.</div><div><br>On Monday, September 16, 2013 6:20:37 AM=
UTC-4, Vittorio Romeo wrote:</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(20=
4, 204, 204); border-left-width: 1px; border-left-style: solid;"><div dir=
=3D"ltr">Indeed, I think this is not a problem that can be solved with the =
current language features. But it is still a problem that has to be solved.=
<br>In my opinion, the best course of action is having some syntax, that, w=
hen applied to arguments, makes the compiler generate the 2^n combinations =
of const& and &&.<br><br>Instead of introducing new keywords/sy=
mbols, why not use <b>std::sink </b>as a special identifier, similarly to s=
td::initializer_list?<br><br><div style=3D"border: 1px solid rgb(187, 187, =
187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code><=
div><span style=3D"color: rgb(0, 0, 136);">void</span><font color=3D"#00000=
0"><span style=3D"color: rgb(0, 0, 0);"> singleSinkFunc</span></font><span =
style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, =
0);">std</span><span style=3D"color: rgb(102, 102, 0);">::</span><span styl=
e=3D"color: rgb(0, 0, 0);">sink</span><span style=3D"color: rgb(102, 102, 0=
);"><</span><span style=3D"color: rgb(102, 0, 102);">Expen<wbr>siveType<=
/span><span style=3D"color: rgb(102, 102, 0);">></span><font color=3D"#0=
00000"><span style=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: =
rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><sp=
an style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, =
0, 0);"> doSomething</span><span style=3D"color: rgb(102, 102, 0);">(</span=
><span style=3D"color: rgb(0, 0, 0);">a</span><span style=3D"color: rgb(102=
, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);=
"> <br></span><span style=3D"color: rgb(136, 0, 0);">// v--- TRANSLATES TO =
---v</span><span style=3D"color: rgb(0, 0, 0);"><br><br></span></font><span=
style=3D"color: rgb(0, 0, 136);">void</span><font color=3D"#000000"><span =
style=3D"color: rgb(0, 0, 0);"> singleSinkFunc</span></font><span style=3D"=
color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102);">=
ExpensiveType</span><font color=3D"#666600"><span style=3D"color: rgb(102, =
102, 0);">&&</span></font><font color=3D"#000000"><span style=3D"co=
lor: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, 102, 0);">)</sp=
an><span style=3D"color: rgb(0, 0, 0);"> </span><span s=
tyle=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0=
);"> doSomething</span><span style=3D"color: rgb(102, 102, 0);">(</span><sp=
an style=3D"color: rgb(0, 0, 0);">std</span><span style=3D"color: rgb(102, =
102, 0);">::</span><span style=3D"color: rgb(0, 0, 0);">move</span><span st=
yle=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0)=
;">a</span><span style=3D"color: rgb(102, 102, 0);">));</span><span style=
=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">=
}</span><span style=3D"color: rgb(0, 0, 0);"><br></span></font><span style=
=3D"color: rgb(0, 0, 136);">void</span><font color=3D"#000000"><span style=
=3D"color: rgb(0, 0, 0);"> singleSinkFunc</span></font><span style=3D"color=
: rgb(102, 102, 0);">(</span><font color=3D"#000000"><span style=3D"color: =
rgb(0, 0, 136);">const</span><span style=3D"color: rgb(0, 0, 0);"> </span><=
/font><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><font co=
lor=3D"#666600"><span style=3D"color: rgb(102, 102, 0);">&</span></font=
><font color=3D"#000000"><span style=3D"color: rgb(0, 0, 0);"> a</span><spa=
n style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0=
, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=
=3D"color: rgb(0, 0, 0);"> doSomething</span><span style=3D"color: rgb(102,=
102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">a</span><span style=
=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"=
> </span><span style=3D"color: rgb(102, 102, 0);">}</span></font></div></co=
de></div><br><div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap:=
break-word; background-color: rgb(250, 250, 250);"><code><div><font color=
=3D"#660066"><span style=3D"color: rgb(0, 0, 136);">void</span><span style=
=3D"color: rgb(0, 0, 0);"> doubleSinkFunc</span><span style=3D"color: rgb(1=
02, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">std</span><span =
style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0,=
0);">sink</span><span style=3D"color: rgb(102, 102, 0);"><</span><span =
style=3D"color: rgb(102, 0, 102);">Expen<wbr>siveType</span><span style=3D"=
color: rgb(102, 102, 0);">></span><span style=3D"color: rgb(0, 0, 0);"> =
a</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=3D"col=
or: rgb(0, 0, 0);"> </span></font><span style=3D"color: rgb(0, 0, 0);">std<=
/span><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"colo=
r: rgb(0, 0, 0);">sink</span><span style=3D"color: rgb(102, 102, 0);"><<=
/span><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><span st=
yle=3D"color: rgb(102, 102, 0);">></span><span style=3D"color: rgb(0, 0,=
0);"> b</span><span style=3D"color: rgb(102, 102, 0);">)</span><span style=
=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">=
{</span><span style=3D"color: rgb(0, 0, 0);"> doSomething</span><span style=
=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">=
a</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=3D"col=
or: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);">);</sp=
an><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(1=
02, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span=
style=3D"color: rgb(136, 0, 0);">// v--- TRANSLATES TO ---v</span><span st=
yle=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"color: rgb(0, 0,=
136);">void</span><span style=3D"color: rgb(0, 0, 0);"> doubleSinkFunc</sp=
an><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: r=
gb(102, 0, 102);">ExpensiveType</span><span style=3D"color: rgb(102, 102, 0=
);">&&</span><span style=3D"color: rgb(0, 0, 0);"> a</span><span st=
yle=3D"color: rgb(102, 102, 0);">,</span><font color=3D"#000000"><span styl=
e=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 0, 102);"=
>ExpensiveType</span><span style=3D"color: rgb(102, 102, 0);">&&</s=
pan><span style=3D"color: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb=
(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> =
</span><span style=3D"color: rgb(102, 102, 0);"=
>{</span><span style=3D"color: rgb(0, 0, 0);"> doSomething</span><span styl=
e=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);"=
>std</span><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D=
"color: rgb(0, 0, 0);">move</span><span style=3D"color: rgb(102, 102, 0);">=
(</span><span style=3D"color: rgb(0, 0, 0);">a</span><span style=3D"color: =
rgb(102, 102, 0);">),</span><span style=3D"color: rgb(0, 0, 0);"> std</span=
><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rg=
b(0, 0, 0);">move</span><span style=3D"color: rgb(102, 102, 0);">(</span><s=
pan style=3D"color: rgb(0, 0, 0);">b</span><span style=3D"color: rgb(102, 1=
02, 0);">));</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);">=
<br></span></font><span style=3D"color: rgb(0, 0, 136);">void</span><span s=
tyle=3D"color: rgb(0, 0, 0);"> doubleSinkFunc</span><span style=3D"color: r=
gb(102, 102, 0);">(</span><font color=3D"#000000"><span style=3D"color: rgb=
(0, 0, 136);">const</span><span style=3D"color: rgb(0, 0, 0);"> </span></fo=
nt><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><font color=
=3D"#666600"><span style=3D"color: rgb(102, 102, 0);">&</span></font><s=
pan style=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, =
102, 0);">,</span><font color=3D"#000000"><span style=3D"color: rgb(0, 0, 0=
);"> </span><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><s=
pan style=3D"color: rgb(102, 102, 0);">&&</span><span style=3D"colo=
r: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);">)</span=
><span style=3D"color: rgb(0, 0, 0);"> </span><span st=
yle=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0)=
;"> doSomething</span><span style=3D"color: rgb(102, 102, 0);">(</span><spa=
n style=3D"color: rgb(0, 0, 0);">a</span><span style=3D"color: rgb(102, 102=
, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"> std</span><span style=
=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0, 0);"=
>move</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D=
"color: rgb(0, 0, 0);">b</span><span style=3D"color: rgb(102, 102, 0);">));=
</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: r=
gb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br></span><=
/font><span style=3D"color: rgb(0, 0, 136);">void</span><span style=3D"colo=
r: rgb(0, 0, 0);"> doubleSinkFunc</span><span style=3D"color: rgb(102, 102,=
0);">(</span><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span>=
<font color=3D"#666600"><span style=3D"color: rgb(102, 102, 0);">&</spa=
n></font><span style=3D"color: rgb(102, 102, 0);">&</span><span style=
=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, 102, 0);"=
>,</span><span style=3D"color: rgb(0, 0, 0);"> </span><font color=3D"#00000=
0"><span style=3D"color: rgb(0, 0, 0);"> </span></font><font color=3D"=
#000000"><span style=3D"color: rgb(0, 0, 136);">const</span><span style=3D"=
color: rgb(0, 0, 0);"> </span></font><span style=3D"color: rgb(102, 0, 102)=
;">ExpensiveType</span><font color=3D"#666600"><span style=3D"color: rgb(10=
2, 102, 0);">&</span></font><font color=3D"#000000"><span style=3D"colo=
r: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);">)</span=
><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);=
"> doSomething</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
style=3D"color: rgb(0, 0, 0);">std</span><span style=3D"color: rgb(102, 10=
2, 0);">::</span><span style=3D"color: rgb(0, 0, 0);">move</span><span styl=
e=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);"=
>a</span><span style=3D"color: rgb(102, 102, 0);">),</span><span style=3D"c=
olor: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);">);</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br></span></f=
ont><span style=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color:=
rgb(0, 0, 0);"> doubleSinkFunc</span><span style=3D"color: rgb(102, 102, 0=
);">(</span><font color=3D"#000000"><span style=3D"color: rgb(0, 0, 136);">=
const</span><span style=3D"color: rgb(0, 0, 0);"> </span></font><span style=
=3D"color: rgb(102, 0, 102);">ExpensiveType</span><font color=3D"#666600"><=
span style=3D"color: rgb(102, 102, 0);">&</span></font><span style=3D"c=
olor: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, 102, 0);">,</s=
pan><span style=3D"color: rgb(0, 0, 0);"> </span><font color=3D"#000000"><s=
pan style=3D"color: rgb(0, 0, 0);"> </span></font><font color=3D"#0000=
00"><span style=3D"color: rgb(0, 0, 136);">const</span><span style=3D"color=
: rgb(0, 0, 0);"> </span></font><span style=3D"color: rgb(102, 0, 102);">Ex=
pensiveType</span><font color=3D"#666600"><span style=3D"color: rgb(102, 10=
2, 0);">&</span></font><font color=3D"#000000"><span style=3D"color: rg=
b(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);">)</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102=
, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"> doSomething</span><spa=
n style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0=
, 0);">a</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=
=3D"color: rgb(0, 0, 0);"> b</span><span style=3D"color: rgb(102, 102, 0);"=
>);</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color=
: rgb(102, 102, 0);">}</span></font><font color=3D"#000000"><span style=3D"=
color: rgb(0, 0, 0);"><br></span></font></div></code></div><br><br><br>Alte=
rnative ideas for syntax:<div><br></div><div><div style=3D"border: 1px soli=
d rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250=
, 250);"><code><div><font color=3D"#660066"><span style=3D"color: rgb(0, 0,=
136);">void</span><span style=3D"color: rgb(0, 0, 0);"> sinkFunc</span><sp=
an style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, =
0, 0);">std</span><span style=3D"color: rgb(102, 102, 0);">::</span><span s=
tyle=3D"color: rgb(0, 0, 136);">in</span><span style=3D"color: rgb(102, 102=
, 0);"><</span><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</s=
pan><span style=3D"color: rgb(102, 102, 0);"><wbr>></span><span style=3D=
"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, 102, 0);">);=
</span><span style=3D"color: rgb(0, 0, 0);"><br></span></font><span style=
=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"=
> sinkFunc</span><span style=3D"color: rgb(102, 102, 0);">(</span><font col=
or=3D"#000000"><span style=3D"color: rgb(102, 102, 0);">></span></font><=
span style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><span style=3D"=
color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 0);"> =
a</span><span style=3D"color: rgb(102, 102, 0);">);</span><span style=3D"co=
lor: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);">void<=
/span><span style=3D"color: rgb(0, 0, 0);"> sinkFunc</span><span style=3D"c=
olor: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102);">E=
xpensiveType</span><span style=3D"color: rgb(102, 102, 0);"><<</span>=
<span style=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102=
, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span =
style=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0,=
0);"> sinkFunc</span><span style=3D"color: rgb(102, 102, 0);">(</span><spa=
n style=3D"color: rgb(102, 0, 102);">ExpensiveType</span><font color=3D"#66=
6600"><span style=3D"color: rgb(0, 0, 0);"> sink</span></font><span style=
=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, 102, 0);"=
>);</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"co=
lor: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"> sink=
Func</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"=
color: rgb(0, 0, 0); font-family: Arial,Helvetica,sans-serif; font-size: 13=
px;"><span style=3D"color: rgb(0, 0, 0);">sink </span></span><span style=3D=
"color: rgb(102, 0, 102);">ExpensiveType</span><font color=3D"#666600" styl=
e=3D"font-family: Arial,Helvetica,sans-serif; font-size: 13px;"><span style=
=3D"color: rgb(0, 0, 0);"> </span></font><span style=3D"color: rgb(0, 0, 0)=
;">a</span><span style=3D"color: rgb(102, 102, 0);">);</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);">vo=
id</span><span style=3D"color: rgb(0, 0, 0);"> sinkFunc</span><span style=
=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102=
);">ExpensiveType</span><font color=3D"#666600"><span style=3D"color: rgb(0=
, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">in</span></font><s=
pan style=3D"color: rgb(0, 0, 0);"> a</span><span style=3D"color: rgb(102, =
102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span st=
yle=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0=
);"> sinkFunc</span><span style=3D"color: rgb(102, 102, 0);">(</span><span =
style=3D"font-family: Arial,Helvetica,sans-serif; font-size: 13px;"><span s=
tyle=3D"color: rgb(0, 0, 136);">in</span><span style=3D"color: rgb(0, 0, 0)=
;"> </span></span><span style=3D"color: rgb(102, 0, 102);">ExpensiveType</s=
pan><font color=3D"#666600" style=3D"font-family: Arial,Helvetica,sans-seri=
f; font-size: 13px;"><span style=3D"color: rgb(0, 0, 0);"> </span></font><s=
pan style=3D"color: rgb(0, 0, 0);">a</span><span style=3D"color: rgb(102, 1=
02, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"><br></span></div></c=
ode></div><br><br><br><br></div></div></blockquote></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_4735_2553645.1379344051381--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Mon, 16 Sep 2013 09:15:17 -0700
Raw View
--047d7b3a9a7cfc614804e68284c8
Content-Type: text/plain; charset=ISO-8859-1
Can you post the benchmark code? Not that I don't trust you, but 1-2% is
well within the margin of error in most cases. In particular, any time you
involve IO (e.g. std::cout) that's going to play havoc with benchmarks.
Regarding your code example, that API is poor for 2 reasons:
1. doing in a way that is exception safe is impossible. The way to make it
exception safe is just to make copies.
2. that interface forces creation of a new vector on every call.
3. you have way too many unnecessary moves in that example -- use emplace
where possible. If T was something like std::array, move is not cheaper
than copy.
You can fix (1) using something like:
// Note: I'm no initializer_list expert -- you may need to
// have some kind of wrapper type if it isn't legal to take
// a const&.
std::vector<matrix>
add_scalar(std::initializer_list<matrix const&> matrices,
std::initializer_list<int> scalars)
{
if(matrices.size() != scalars.size()) {
assert(false && "Matrix scalar size mismatch!");
std::terminate(); // Don't throw for things that should terminate!
}
// Make exception safe copy:
std::vector<matrix> result(begin(matricies), end(matricies));
auto si = begin(scalars); // Nothrow
for(matrix& m : result) // Norhrow
{
m += *si++; // Nothrow
}
return result;
}
Most importantly though, this is a niche case, not a common case. The
original proposal was trying to support the common case of having a
constructor with a sink argument. That is a compelling reason to add things
to the standard -- I'm not sure this is, even in the couple of places where
it may make sense..
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Sun, Sep 15, 2013 at 4:48 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> Thanks for the detailed analysis. I agree that in<T> is slightly better in
> some cases and slightly inferior in others. I ran a benchmark and saw about
> 1-2% improvement in performance when using in<T> as opposed to the example
> #2 you proposed. Each run of the benchmark executed all 4 versions
> (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of binary
> operator+ with equal probability (rand() % 4).
>
> 1 to 2 % performance gain may or may not be "worth" it. People should use
> their judgement. However, story does not end here.
>
> Binary operator +() provides only one opportunity for in<T> to save a
> copy. I.e., when the right hand side object is an rvalue. The in<T> idiom
> shines the most when there are more opportunities to detect rvalues and to
> exploit them at run-time. So here is a small function to add scalars to a
> list of matrices.
>
> std::vector<matrix>
> add_scalar(std::initializer_list<in<matrix>> matrices,
> std::initializer_list<int> scalars)
> {
> if(matrices.size() != scalars.size())
> throw 0;
>
> std::vector<matrix> result;
> result.reserve(matrices.size());
>
> auto si = begin(scalars);
> for(const in<matrix> & m : matrices)
> {
> if(m.rvalue()) {
> cout << "rvalue matrix\n";
> result.push_back(std::move(m.rget() += *si));
> }
> else {
> cout << "lvalue matrix\n";
> result.push_back(std::move(matrix(m) += *si));
> }
> }
>
> return result;
> }
>
> And I call it like this:
>
> matrix s1, s2, s3, s4;
> add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
>
> I tested this code on g++ 4.9 and clang 3.3.
>
> In each use, this function gives finite but unknown number of
> opportunities to exploit move-semantics. I'm not sure if such a function
> can be easily implemented using universal references. Variadic templates
> come to mind but two lists of parameters probably requires separate
> grouping. I guess it could be done using std::tuple and two variadic
> parameter packs of universal references. But std::make_tuple is not as
> pretty as std::initializer_list.
>
> Surprisingly, in<T> works nicely with initializer_list<T>. Initilizer_list
> does not appear to retain rvalue/lvalue-ness of the original parameter
> because initializer_list iterator is a pointer to consts. In<T>, however,
> allows the rvalue/lvalue knowledge of the original parameter pass through
> the initializer_list--here is the best part--without subverting
> const-correctness. All member functions in in<T> are const.
>
> Thoughts?
>
> Sumant
>
> --
>
> ---
> 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/.
--047d7b3a9a7cfc614804e68284c8
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Can you post the benchmark code? Not that I don't=
trust you, but 1-2% is well within the margin of error in most cases. In p=
articular, any time you involve IO (e.g. std::cout) that's going to pla=
y havoc with benchmarks.</div>
<div>=A0</div><div>Regarding your code example, that API is poor for 2 reas=
ons:</div><div>1. doing in a way that is exception safe is impossible. The =
way to make it exception safe is just to make copies.</div><div>2. that int=
erface forces creation of a new vector on every call.</div>
<div>3. you have way too many unnecessary moves in that example -- use empl=
ace where possible. If T was something like std::array, move is not cheaper=
than copy.</div><div><div>=A0</div><div>You can fix (1) using something li=
ke:</div>
<div>// Note: I'm no initializer_list expert -- you may need to<br>// h=
ave some kind of wrapper type if it isn't legal to take<br>// a const&a=
mp;.<br>std::vector<matrix><br>add_scalar(std::initializer_list<ma=
trix const&> matrices,<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 std::initializer_list<int> scalars)<br=
>{<br>=A0 if(matrices.size() !=3D scalars.size()) {<br>=A0=A0=A0 assert(fal=
se && "Matrix scalar size mismatch!");<br>=A0=A0=A0 std::=
terminate(); // Don't throw for things that should terminate!<br>
=A0 }<br>=A0 <br>=A0 // Make exception safe copy:<br>=A0 std::vector<mat=
rix> result(begin(matricies), end(matricies));<br>=A0 auto si =3D begin(=
scalars); // Nothrow<br>=A0 for(matrix& m : result) // Norhrow<br>=A0 {=
<br>=A0=A0=A0=A0 m +=3D *si++; // Nothrow<br>
=A0 }<br>=A0 <br>=A0 return result;<br>}</div></div><div>=A0</div><div>Most=
importantly though, this is a niche case, not a common case. The original =
proposal was trying to support the common case of having a constructor with=
a sink argument. That is a compelling reason to add things to the standard=
-- I'm not sure this is, even in the couple of places where it may mak=
e sense..</div>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>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://=
stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sun, Sep 15, 2013 at 4:48 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D"=
_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4).=A0<br=
>
</div><div><br></div><div>1 to 2 % performance gain may or may not be "=
;worth" it. People should use their judgement. However, story does not=
end here.</div><div><br></div><div>Binary operator +() provides only one o=
pportunity for in<T> to save a copy. I.e., =A0when the right hand sid=
e object is an rvalue. The in<T> idiom shines the most when there are=
more opportunities to detect rvalues and to exploit them at run-time. So h=
ere is a small function to add scalars to a list of matrices.=A0</div>
<div><br></div><div><div>std::vector<matrix></div><div>add_scalar(std=
::initializer_list<in<matrix>> matrices,</div><div>=A0 =A0 =A0 =
=A0 =A0 =A0std::initializer_list<int> scalars)</div><div>{</div><div>=
=A0 if(matrices.size() !=3D scalars.size())</div>
<div>=A0 =A0 throw 0;</div><div><br></div><div>=A0 std::vector<matrix>=
; result;</div><div>=A0 result.reserve(matrices.size());</div><div>=A0=A0</=
div><div>=A0 auto si =3D begin(scalars);</div><div>=A0 for(const in<matr=
ix> & m : matrices)</div>
<div>=A0 {</div><div>=A0 =A0 =A0if(m.rvalue()) {</div><div>=A0 =A0 =A0 =A0 =
cout << "rvalue matrix\n";</div><div>=A0 =A0 =A0 =A0 result=
..push_back(std::move(m.rget() +=3D *si));</div><div>=A0 =A0 =A0}</div><div>=
=A0 =A0 =A0else {</div><div>=A0 =A0 =A0 =A0 cout << "lvalue matr=
ix\n";</div>
<div>=A0 =A0 =A0 =A0 result.push_back(std::move(matrix(m) +=3D *si));</div>=
<div>=A0 =A0 =A0}</div><div>=A0 }</div><div><br></div><div>=A0 return resul=
t;</div><div>}</div><div><br></div><div>And I call it like this:</div><div>=
<div><br></div>
<div>
matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { =
3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g++ 4.9 =
and clang 3.3.</div><div><br></div><div>In each use, this function gives fi=
nite but unknown number of opportunities to exploit move-semantics. I'm=
not sure if such a function can be easily implemented using universal refe=
rences. Variadic templates come to mind but two lists of parameters probabl=
y requires separate grouping. I guess it could be done using std::tuple and=
two variadic parameter packs of universal references. But std::make_tuple =
is not as pretty as std::initializer_list.</div>
<div><br></div><div>Surprisingly, in<T> works nicely with initializer=
_list<T>. Initilizer_list does not appear to retain rvalue/lvalue-nes=
s of the original parameter because initializer_list iterator is a pointer =
to consts. In<T>, however, allows the rvalue/lvalue knowledge of the =
original parameter pass through the initializer_list--here is the best part=
--without subverting const-correctness. All member functions in in<T>=
are const. =A0</div>
<div><br></div><div>Thoughts?</div><span class=3D"HOEnZb"><font color=3D"#8=
88888"><div><br></div><div>Sumant</div><br></font></span></div></div><div c=
lass=3D"HOEnZb"><div class=3D"h5">
<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>
</div></div></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 />
--047d7b3a9a7cfc614804e68284c8--
.
Author: Alex B <devalexb@gmail.com>
Date: Mon, 16 Sep 2013 13:49:04 -0400
Raw View
--bcaec52998b5ffd44c04e683d117
Content-Type: text/plain; charset=ISO-8859-1
Thinking about it, maybe concepts will be able to (quite elegantly) solve
this problem. Consider a Sink concept (rename it to whatever you
like/appropriate).
template <class T, class U>
concept bool Sink()
{
return is_base_of<T, decay_t<U>>::value;
}
template <class T>
constexpr bool is_mutable_rvalue = !is_const<T>::value &&
(is_rvalue_reference<T>::value || !is_reference<T>::value);
template <class T>
T& make_mutable(const T& t)
{
return const_cast<T&>(t);
}
template <Sink<matrix> A, Sink<matrix> B>
matrix operator+(A a, B b)
{
return move(
is_mutable_rvalue<A> ? make_mutable(a) += b :
is_mutable_rvalue<B> ? make_mutable(b) += a :
matrix(a) += b);
}
On Mon, Sep 16, 2013 at 11:07 AM, Alex B <devalexb@gmail.com> wrote:
> How do you get a function pointer to one of the four specialization of
> doubleSinkFunc?
>
> Idea of a terse notation sounds nice (sink, in, ...), but if it is a
> template, there must at least be a way to declare it using the "template"
> keyword, so that we could mark it explicitly that it needs to be
> parameterized. And then we could get a pointer to the function taking
> "const &" by specifying the parameter with a syntax
> like "doubleSinkFunc<const &>". After all, it *is* a template, so we
> should be able to mark it and deal with it explicitly.
>
> On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wrote:
>
>> Indeed, I think this is not a problem that can be solved with the current
>> language features. But it is still a problem that has to be solved.
>> In my opinion, the best course of action is having some syntax, that,
>> when applied to arguments, makes the compiler generate the 2^n combinations
>> of const& and &&.
>>
>> Instead of introducing new keywords/symbols, why not use *std::sink *as
>> a special identifier, similarly to std::initializer_list?
>>
>> void singleSinkFunc(std::sink<Expen**siveType> a) { doSomething(a); }
>> // v--- TRANSLATES TO ---v
>>
>> void singleSinkFunc(ExpensiveType&& a) { doSomething(std::move(a));
>> }
>> void singleSinkFunc(const ExpensiveType& a) { doSomething(a); }
>>
>> void doubleSinkFunc(std::sink<Expen**siveType> a, std::sink<ExpensiveType
>> > b) { doSomething(a, b); }
>> // v--- TRANSLATES TO ---v
>>
>> void doubleSinkFunc(ExpensiveType&& a, ExpensiveType&& b) {doSomething
>> (std::move(a), std::move(b)); }
>> void doubleSinkFunc(const ExpensiveType& a, ExpensiveType&& b) {doSomething
>> (a, std::move(b)); }
>> void doubleSinkFunc(ExpensiveType&& a, const ExpensiveType& b) {doSomething
>> (std::move(a), b); }
>> void doubleSinkFunc(const ExpensiveType& a, const ExpensiveType& b) {doSomething
>> (a, b); }
>>
>>
>>
>> Alternative ideas for syntax:
>>
>> void sinkFunc(std::in<ExpensiveType**> a);
>> void sinkFunc(>ExpensiveType< a);
>> void sinkFunc(ExpensiveType<< a);
>> void sinkFunc(ExpensiveType sink a);
>> void sinkFunc(sink ExpensiveType a);
>> void sinkFunc(ExpensiveType in a);
>> void sinkFunc(in ExpensiveType a);
>>
>>
>>
>>
>> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.
--bcaec52998b5ffd44c04e683d117
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Thinking about it, maybe concepts will be able to (quite e=
legantly) solve this problem. Consider a Sink concept (rename it to whateve=
r you like/appropriate).<div><br><div><br></div><div><div><font face=3D"cou=
rier new, monospace">template <class T, class U></font></div>
<div><font face=3D"courier new, monospace">concept bool Sink()</font></div>=
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace"><span style=3D"white-space:pre">=A0 </span>return=
is_base_of<T, decay_t<U>>::value;</font></div>
<div><font face=3D"courier new, monospace">}</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><div><font face=3D"courier n=
ew, monospace">template <class T></font></div><div><font face=3D"cour=
ier new, monospace">constexpr bool is_mutable_rvalue =3D !is_const<T>=
::value && (is_rvalue_reference<T>::value || !is_reference<=
;T>::value);</font></div>
</div><div><font face=3D"courier new, monospace"><br></font></div><div><fon=
t face=3D"courier new, monospace">template <class T></font></div><div=
><font face=3D"courier new, monospace">T& make_mutable(const T& t)<=
/font></div>
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace">=A0 =A0return const_cast<T&>(t);</font><=
/div><div><font face=3D"courier new, monospace">}</font></div><div><br></di=
v><div>
<font face=3D"courier new, monospace"><br></font></div><div><font face=3D"c=
ourier new, monospace">template <Sink<matrix> A, Sink<matrix>=
; B></font></div><div><font face=3D"courier new, monospace">matrix opera=
tor+(A a, B b)</font></div>
</div><div><font face=3D"courier new, monospace">{</font></div><div><font f=
ace=3D"courier new, monospace">=A0 =A0return move(</font></div><div><font f=
ace=3D"courier new, monospace">=A0 =A0 =A0=A0</font><span style=3D"font-fam=
ily:'courier new',monospace">is_mutable_rvalue</span><font face=3D"=
courier new, monospace"><A> ? make_mutable(a) +=3D b :</font></div>
<div><font face=3D"courier new, monospace">=A0 =A0 =A0=A0</font><span style=
=3D"font-family:'courier new',monospace">is_mutable_rvalue</span><f=
ont face=3D"courier new, monospace"><B> ? make_mutable(b) +=3D a :</f=
ont></div><div>
<font face=3D"courier new, monospace">=A0 =A0 =A0 matrix(a) +=3D b);</font>=
</div><div><font face=3D"courier new, monospace">}</font></div><div class=
=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><br><div class=3D"gma=
il_quote">On Mon, Sep 16, 2013 at 11:07 AM, Alex B <span dir=3D"ltr"><<a=
href=3D"mailto:devalexb@gmail.com" target=3D"_blank">devalexb@gmail.com</a=
>></span> wrote:<br>
<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;p=
adding-left:1ex"><div dir=3D"ltr"><div>How do you get a function pointer to=
one of the four specialization of doubleSinkFunc?</div>
<div>=A0</div><div>Idea of a terse notation sounds nice (sink, in, ...), bu=
t if it is a template, there must at least be a way to declare it using the=
"template" keyword, so that we could mark it explicitly that it =
needs to be parameterized. And then we could get a pointer to the function =
taking "const &"=A0by specifying the parameter with a syntax =
like=A0"doubleSinkFunc<const &>". After all, it <em>is<=
/em> a template, so we should be able to mark it and deal with it explicitl=
y.</div>
<div><br>On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px=
;border-left-style:solid">
<div dir=3D"ltr">Indeed, I think this is not a problem that can be solved w=
ith the current language features. But it is still a problem that has to be=
solved.<br>In my opinion, the best course of action is having some syntax,=
that, when applied to arguments, makes the compiler generate the 2^n combi=
nations of const& and &&.<br>
<br>Instead of introducing new keywords/symbols, why not use <b>std::sink <=
/b>as a special identifier, similarly to std::initializer_list?<br><br><div=
style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;background=
-color:rgb(250,250,250)">
<code><div><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"#00=
0000"><span style> singleSinkFunc</span></font><span style=3D"color:rgb(102=
,102,0)">(</span><span style>std</span><span style=3D"color:rgb(102,102,0)"=
>::</span><span style>sink</span><span style=3D"color:rgb(102,102,0)"><<=
/span><span style=3D"color:rgb(102,0,102)">Expen<u></u>siveType</span><span=
style=3D"color:rgb(102,102,0)">></span><font color=3D"#000000"><span st=
yle> a</span><span style=3D"color:rgb(102,102,0)">)</span><span style> </sp=
an><span style=3D"color:rgb(102,102,0)">{</span><span style> doSomething</s=
pan><span style=3D"color:rgb(102,102,0)">(</span><span style>a</span><span =
style=3D"color:rgb(102,102,0)">);</span><span style> </span><span style=3D"=
color:rgb(102,102,0)">}</span><span style> <br>
</span><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span style><br><br></span></font><span style=3D"color:rgb(0,0,136)">void</=
span><font color=3D"#000000"><span style> singleSinkFunc</span></font><span=
style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)=
">ExpensiveType</span><font color=3D"#666600"><span style=3D"color:rgb(102,=
102,0)">&&</span></font><font color=3D"#000000"><span style> a</spa=
n><span style=3D"color:rgb(102,102,0)">)</span><span style> =A0 =A0 =A0</sp=
an><span style=3D"color:rgb(102,102,0)">{</span><span style> doSomething</s=
pan><span style=3D"color:rgb(102,102,0)">(</span><span style>std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style>move</span><span styl=
e=3D"color:rgb(102,102,0)">(</span><span style>a</span><span style=3D"color=
:rgb(102,102,0)">));</span><span style> </span><span style=3D"color:rgb(102=
,102,0)">}</span><span style><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"=
#000000"><span style> singleSinkFunc</span></font><span style=3D"color:rgb(=
102,102,0)">(</span><font color=3D"#000000"><span style=3D"color:rgb(0,0,13=
6)">const</span><span style> </span></font><span style=3D"color:rgb(102,0,1=
02)">ExpensiveType</span><font color=3D"#666600"><span style=3D"color:rgb(1=
02,102,0)">&</span></font><font color=3D"#000000"><span style> a</span>=
<span style=3D"color:rgb(102,102,0)">)</span><span style> </span><span styl=
e=3D"color:rgb(102,102,0)">{</span><span style> doSomething</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style>a</span><span style=3D"colo=
r:rgb(102,102,0)">);</span><span style> </span><span style=3D"color:rgb(102=
,102,0)">}</span></font></div>
</code></div><br><div style=3D"border:1px solid rgb(187,187,187);word-wrap:=
break-word;background-color:rgb(250,250,250)"><code><div><font color=3D"#66=
0066"><span style=3D"color:rgb(0,0,136)">void</span><span style> doubleSink=
Func</span><span style=3D"color:rgb(102,102,0)">(</span><span style>std</sp=
an><span style=3D"color:rgb(102,102,0)">::</span><span style>sink</span><sp=
an style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(102,0=
,102)">Expen<u></u>siveType</span><span style=3D"color:rgb(102,102,0)">>=
</span><span style> a</span><span style=3D"color:rgb(102,102,0)">,</span><s=
pan style> </span></font><span style>std</span><span style=3D"color:rgb(102=
,102,0)">::</span><span style>sink</span><span style=3D"color:rgb(102,102,0=
)"><</span><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><spa=
n style=3D"color:rgb(102,102,0)">></span><span style> b</span><span styl=
e=3D"color:rgb(102,102,0)">)</span><span style> </span><span style=3D"color=
:rgb(102,102,0)">{</span><span style> doSomething</span><span style=3D"colo=
r:rgb(102,102,0)">(</span><span style>a</span><span style=3D"color:rgb(102,=
102,0)">,</span><span style> b</span><span style=3D"color:rgb(102,102,0)">)=
;</span><span style> </span><span style=3D"color:rgb(102,102,0)">}</span><s=
pan style><br>
</span><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span style><br><br></span><span style=3D"color:rgb(0,0,136)">void</span><s=
pan style> doubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</spa=
n><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"c=
olor:rgb(102,102,0)">&&</span><span style> a</span><span style=3D"c=
olor:rgb(102,102,0)">,</span><font color=3D"#000000"><span style> </span><s=
pan style=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"color=
:rgb(102,102,0)">&&</span><span style> b</span><span style=3D"color=
:rgb(102,102,0)">)</span><span style> =A0 =A0 =A0 =A0 =A0 =A0</span><span s=
tyle=3D"color:rgb(102,102,0)">{</span><span style> doSomething</span><span =
style=3D"color:rgb(102,102,0)">(</span><span style>std</span><span style=3D=
"color:rgb(102,102,0)">::</span><span style>move</span><span style=3D"color=
:rgb(102,102,0)">(</span><span style>a</span><span style=3D"color:rgb(102,1=
02,0)">),</span><span style> std</span><span style=3D"color:rgb(102,102,0)"=
>::</span><span style>move</span><span style=3D"color:rgb(102,102,0)">(</sp=
an><span style>b</span><span style=3D"color:rgb(102,102,0)">));</span><span=
style> </span><span style=3D"color:rgb(102,102,0)">}</span><span style><br=
>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span style> do=
ubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=
=3D"#000000"><span style=3D"color:rgb(0,0,136)">const</span><span style> </=
span></font><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font =
color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&</span></font><=
span style> a</span><span style=3D"color:rgb(102,102,0)">,</span><font colo=
r=3D"#000000"><span style> </span><span style=3D"color:rgb(102,0,102)">Expe=
nsiveType</span><span style=3D"color:rgb(102,102,0)">&&</span><span=
style> b</span><span style=3D"color:rgb(102,102,0)">)</span><span style> =
=A0 =A0 =A0 </span><span style=3D"color:rgb(102,102,0)">{</span><span style=
> doSomething</span><span style=3D"color:rgb(102,102,0)">(</span><span styl=
e>a</span><span style=3D"color:rgb(102,102,0)">,</span><span style> std</sp=
an><span style=3D"color:rgb(102,102,0)">::</span><span style>move</span><sp=
an style=3D"color:rgb(102,102,0)">(</span><span style>b</span><span style=
=3D"color:rgb(102,102,0)">));</span><span style> </span><span style=3D"colo=
r:rgb(102,102,0)">}</span><span style><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span style> do=
ubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span=
style=3D"color:rgb(102,102,0)">&</span></font><span style=3D"color:rgb=
(102,102,0)">&</span><span style> a</span><span style=3D"color:rgb(102,=
102,0)">,</span><span style> </span><font color=3D"#000000"><span style>=A0=
</span></font><font color=3D"#000000"><span style=3D"color:rgb(0,0,136)">co=
nst</span><span style> </span></font><span style=3D"color:rgb(102,0,102)">E=
xpensiveType</span><font color=3D"#666600"><span style=3D"color:rgb(102,102=
,0)">&</span></font><font color=3D"#000000"><span style> b</span><span =
style=3D"color:rgb(102,102,0)">)</span><span style> =A0 =A0 =A0</span><span=
style=3D"color:rgb(102,102,0)">{</span><span style> doSomething</span><spa=
n style=3D"color:rgb(102,102,0)">(</span><span style>std</span><span style=
=3D"color:rgb(102,102,0)">::</span><span style>move</span><span style=3D"co=
lor:rgb(102,102,0)">(</span><span style>a</span><span style=3D"color:rgb(10=
2,102,0)">),</span><span style> b</span><span style=3D"color:rgb(102,102,0)=
">);</span><span style> </span><span style=3D"color:rgb(102,102,0)">}</span=
><span style><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span style> do=
ubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=
=3D"#000000"><span style=3D"color:rgb(0,0,136)">const</span><span style> </=
span></font><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font =
color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&</span></font><=
span style> a</span><span style=3D"color:rgb(102,102,0)">,</span><span styl=
e> </span><font color=3D"#000000"><span style>=A0</span></font><font color=
=3D"#000000"><span style=3D"color:rgb(0,0,136)">const</span><span style> </=
span></font><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font =
color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&</span></font><=
font color=3D"#000000"><span style> b</span><span style=3D"color:rgb(102,10=
2,0)">)</span><span style> </span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span style> doSomething</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style>a</span><span style=3D"color:rgb(102,102,0)">,</span><span=
style> b</span><span style=3D"color:rgb(102,102,0)">);</span><span style> =
</span><span style=3D"color:rgb(102,102,0)">}</span></font><font color=3D"#=
000000"><span style><br>
</span></font></div></code></div><br><br><br>Alternative ideas for syntax:<=
div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);word-wra=
p:break-word;background-color:rgb(250,250,250)"><code><div><font color=3D"#=
660066"><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc=
</span><span style=3D"color:rgb(102,102,0)">(</span><span style>std</span><=
span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,1=
36)">in</span><span style=3D"color:rgb(102,102,0)"><</span><span style=
=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,=
102,0)"><u></u>></span><span style> a</span><span style=3D"color:rgb(102=
,102,0)">);</span><span style><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span style> si=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#0=
00000"><span style=3D"color:rgb(102,102,0)">></span></font><span style=
=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,=
102,0)"><</span><span style> a</span><span style=3D"color:rgb(102,102,0)=
">);</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)"><&=
lt;</span><span style> a</span><span style=3D"color:rgb(102,102,0)">);</spa=
n><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style> sink<=
/span></font><span style> a</span><span style=3D"color:rgb(102,102,0)">);</=
span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-size=
:13px;font-family:Arial,Helvetica,sans-serif"><span style>sink </span></spa=
n><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#=
666600" style=3D"font-family:Arial,Helvetica,sans-serif;font-size:13px"><sp=
an style> </span></font><span style>a</span><span style=3D"color:rgb(102,10=
2,0)">);</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style> </spa=
n><span style=3D"color:rgb(0,0,136)">in</span></font><span style> a</span><=
span style=3D"color:rgb(102,102,0)">);</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> sinkFunc<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-fami=
ly:Arial,Helvetica,sans-serif;font-size:13px"><span style=3D"color:rgb(0,0,=
136)">in</span><span style> </span></span><span style=3D"color:rgb(102,0,10=
2)">ExpensiveType</span><font color=3D"#666600" style=3D"font-family:Arial,=
Helvetica,sans-serif;font-size:13px"><span style> </span></font><span style=
>a</span><span style=3D"color:rgb(102,102,0)">);</span><span style><br>
</span></div></code></div><br><br><br><br></div></div></blockquote></div><s=
pan class=3D""><font color=3D"#888888">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D"_blank">std-pr=
oposals+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></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 />
--bcaec52998b5ffd44c04e683d117--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Mon, 16 Sep 2013 11:04:09 -0700
Raw View
--089e0158b6704fbbec04e6840af3
Content-Type: text/plain; charset=ISO-8859-1
You never want "return move(x)" -- it disables RVO.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Mon, Sep 16, 2013 at 10:49 AM, Alex B <devalexb@gmail.com> wrote:
> Thinking about it, maybe concepts will be able to (quite elegantly) solve
> this problem. Consider a Sink concept (rename it to whatever you
> like/appropriate).
>
>
> template <class T, class U>
> concept bool Sink()
> {
> return is_base_of<T, decay_t<U>>::value;
> }
>
> template <class T>
> constexpr bool is_mutable_rvalue = !is_const<T>::value &&
> (is_rvalue_reference<T>::value || !is_reference<T>::value);
>
> template <class T>
> T& make_mutable(const T& t)
> {
> return const_cast<T&>(t);
> }
>
>
> template <Sink<matrix> A, Sink<matrix> B>
> matrix operator+(A a, B b)
> {
> return move(
> is_mutable_rvalue<A> ? make_mutable(a) += b :
> is_mutable_rvalue<B> ? make_mutable(b) += a :
> matrix(a) += b);
> }
>
>
> On Mon, Sep 16, 2013 at 11:07 AM, Alex B <devalexb@gmail.com> wrote:
>
>> How do you get a function pointer to one of the four specialization of
>> doubleSinkFunc?
>>
>> Idea of a terse notation sounds nice (sink, in, ...), but if it is a
>> template, there must at least be a way to declare it using the "template"
>> keyword, so that we could mark it explicitly that it needs to be
>> parameterized. And then we could get a pointer to the function taking
>> "const &" by specifying the parameter with a syntax
>> like "doubleSinkFunc<const &>". After all, it *is* a template, so we
>> should be able to mark it and deal with it explicitly.
>>
>> On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wrote:
>>
>>> Indeed, I think this is not a problem that can be solved with the
>>> current language features. But it is still a problem that has to be solved.
>>> In my opinion, the best course of action is having some syntax, that,
>>> when applied to arguments, makes the compiler generate the 2^n combinations
>>> of const& and &&.
>>>
>>> Instead of introducing new keywords/symbols, why not use *std::sink *as
>>> a special identifier, similarly to std::initializer_list?
>>>
>>> void singleSinkFunc(std::sink<Expen**siveType> a) { doSomething(a); }
>>> // v--- TRANSLATES TO ---v
>>>
>>> void singleSinkFunc(ExpensiveType&& a) { doSomething(std::move(a));
>>> }
>>> void singleSinkFunc(const ExpensiveType& a) { doSomething(a); }
>>>
>>> void doubleSinkFunc(std::sink<Expen**siveType> a, std::sink<
>>> ExpensiveType> b) { doSomething(a, b); }
>>> // v--- TRANSLATES TO ---v
>>>
>>> void doubleSinkFunc(ExpensiveType&& a, ExpensiveType&& b) {doSomething
>>> (std::move(a), std::move(b)); }
>>> void doubleSinkFunc(const ExpensiveType& a, ExpensiveType&& b) {doSomething
>>> (a, std::move(b)); }
>>> void doubleSinkFunc(ExpensiveType&& a, const ExpensiveType& b) {doSomething
>>> (std::move(a), b); }
>>> void doubleSinkFunc(const ExpensiveType& a, const ExpensiveType& b) {doSomething
>>> (a, b); }
>>>
>>>
>>>
>>> Alternative ideas for syntax:
>>>
>>> void sinkFunc(std::in<ExpensiveType**> a);
>>> void sinkFunc(>ExpensiveType< a);
>>> void sinkFunc(ExpensiveType<< a);
>>> void sinkFunc(ExpensiveType sink a);
>>> void sinkFunc(sink ExpensiveType a);
>>> void sinkFunc(ExpensiveType in a);
>>> void sinkFunc(in ExpensiveType a);
>>>
>>>
>>>
>>>
>>> --
>>
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, 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/.
>
--
---
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/.
--089e0158b6704fbbec04e6840af3
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>You never want "return move(x)" -- it disab=
les RVO.</div></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div =
dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.or=
g/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://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Mon, Sep 16, 2013 at 10:49 AM, Alex B=
<span dir=3D"ltr"><<a href=3D"mailto:devalexb@gmail.com" target=3D"_bla=
nk">devalexb@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex">
<div dir=3D"ltr">Thinking about it, maybe concepts will be able to (quite e=
legantly) solve this problem. Consider a Sink concept (rename it to whateve=
r you like/appropriate).<div><br><div><br></div><div><div><font face=3D"cou=
rier new, monospace">template <class T, class U></font></div>
<div><font face=3D"courier new, monospace">concept bool Sink()</font></div>=
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace"><span style=3D"white-space:pre-wrap">=A0 </span>r=
eturn is_base_of<T, decay_t<U>>::value;</font></div>
<div><font face=3D"courier new, monospace">}</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><div><font face=3D"courier n=
ew, monospace">template <class T></font></div><div><font face=3D"cour=
ier new, monospace">constexpr bool is_mutable_rvalue =3D !is_const<T>=
::value && (is_rvalue_reference<T>::value || !is_reference<=
;T>::value);</font></div>
</div><div><font face=3D"courier new, monospace"><br></font></div><div><fon=
t face=3D"courier new, monospace">template <class T></font></div><div=
><font face=3D"courier new, monospace">T& make_mutable(const T& t)<=
/font></div>
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace">=A0 =A0return const_cast<T&>(t);</font><=
/div><div><font face=3D"courier new, monospace">}</font></div><div><br></di=
v><div>
<font face=3D"courier new, monospace"><br></font></div><div><font face=3D"c=
ourier new, monospace">template <Sink<matrix> A, Sink<matrix>=
; B></font></div><div><font face=3D"courier new, monospace">matrix opera=
tor+(A a, B b)</font></div>
</div><div><font face=3D"courier new, monospace">{</font></div><div><font f=
ace=3D"courier new, monospace">=A0 =A0return move(</font></div><div><font f=
ace=3D"courier new, monospace">=A0 =A0 =A0=A0</font><span style=3D"font-fam=
ily:"courier new",monospace">is_mutable_rvalue</span><font face=
=3D"courier new, monospace"><A> ? make_mutable(a) +=3D b :</font></di=
v>
<div><font face=3D"courier new, monospace">=A0 =A0 =A0=A0</font><span style=
=3D"font-family:"courier new",monospace">is_mutable_rvalue</span>=
<font face=3D"courier new, monospace"><B> ? make_mutable(b) +=3D a :<=
/font></div>
<div>
<font face=3D"courier new, monospace">=A0 =A0 =A0 matrix(a) +=3D b);</font>=
</div><div><font face=3D"courier new, monospace">}</font></div><div class=
=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><br><div class=3D"gma=
il_quote"><div>
<div class=3D"h5">On Mon, Sep 16, 2013 at 11:07 AM, Alex B <span dir=3D"ltr=
"><<a href=3D"mailto:devalexb@gmail.com" target=3D"_blank">devalexb@gmai=
l.com</a>></span> wrote:<br>
</div></div><blockquote class=3D"gmail_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"><div><div class=3D"h5"><div dir=3D"ltr"><div>H=
ow do you get a function pointer to one of the four specialization of doubl=
eSinkFunc?</div>
<div>=A0</div><div>Idea of a terse notation sounds nice (sink, in, ...), bu=
t if it is a template, there must at least be a way to declare it using the=
"template" keyword, so that we could mark it explicitly that it =
needs to be parameterized. And then we could get a pointer to the function =
taking "const &"=A0by specifying the parameter with a syntax =
like=A0"doubleSinkFunc<const &>". After all, it <em>is<=
/em> a template, so we should be able to mark it and deal with it explicitl=
y.</div>
<div><br>On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px=
;border-left-style:solid">
<div dir=3D"ltr">Indeed, I think this is not a problem that can be solved w=
ith the current language features. But it is still a problem that has to be=
solved.<br>In my opinion, the best course of action is having some syntax,=
that, when applied to arguments, makes the compiler generate the 2^n combi=
nations of const& and &&.<br>
<br>Instead of introducing new keywords/symbols, why not use <b>std::sink <=
/b>as a special identifier, similarly to std::initializer_list?<br><br><div=
style=3D"border:1px solid rgb(187,187,187);background-color:rgb(250,250,25=
0)">
<code><div><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"#00=
0000"><span> singleSinkFunc</span></font><span style=3D"color:rgb(102,102,0=
)">(</span><span>std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan>sink</span><span style=3D"color:rgb(102,102,0)"><</span><span style=
=3D"color:rgb(102,0,102)">Expen<u></u>siveType</span><span style=3D"color:r=
gb(102,102,0)">></span><font color=3D"#000000"><span> a</span><span styl=
e=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"color:rgb(1=
02,102,0)">{</span><span> doSomething</span><span style=3D"color:rgb(102,10=
2,0)">(</span><span>a</span><span style=3D"color:rgb(102,102,0)">);</span><=
span> </span><span style=3D"color:rgb(102,102,0)">}</span><span> <br>
</span><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span><br><br></span></font><span style=3D"color:rgb(0,0,136)">void</span><=
font color=3D"#000000"><span> singleSinkFunc</span></font><span style=3D"co=
lor:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)">ExpensiveT=
ype</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&=
;&</span></font><font color=3D"#000000"><span> a</span><span style=3D"c=
olor:rgb(102,102,0)">)</span><span> =A0 =A0 =A0</span><span style=3D"color:=
rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"color:rgb(1=
02,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>a=
</span><span style=3D"color:rgb(102,102,0)">));</span><span> </span><span s=
tyle=3D"color:rgb(102,102,0)">}</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"=
#000000"><span> singleSinkFunc</span></font><span style=3D"color:rgb(102,10=
2,0)">(</span><font color=3D"#000000"><span style=3D"color:rgb(0,0,136)">co=
nst</span><span> </span></font><span style=3D"color:rgb(102,0,102)">Expensi=
veType</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&=
amp;</span></font><font color=3D"#000000"><span> a</span><span style=3D"col=
or:rgb(102,102,0)">)</span><span> </span><span style=3D"color:rgb(102,102,0=
)">{</span><span> doSomething</span><span style=3D"color:rgb(102,102,0)">(<=
/span><span>a</span><span style=3D"color:rgb(102,102,0)">);</span><span> </=
span><span style=3D"color:rgb(102,102,0)">}</span></font></div>
</code></div><br><div style=3D"border:1px solid rgb(187,187,187);background=
-color:rgb(250,250,250)"><code><div><font color=3D"#660066"><span style=3D"=
color:rgb(0,0,136)">void</span><span> doubleSinkFunc</span><span style=3D"c=
olor:rgb(102,102,0)">(</span><span>std</span><span style=3D"color:rgb(102,1=
02,0)">::</span><span>sink</span><span style=3D"color:rgb(102,102,0)"><<=
/span><span style=3D"color:rgb(102,0,102)">Expen<u></u>siveType</span><span=
style=3D"color:rgb(102,102,0)">></span><span> a</span><span style=3D"co=
lor:rgb(102,102,0)">,</span><span> </span></font><span>std</span><span styl=
e=3D"color:rgb(102,102,0)">::</span><span>sink</span><span style=3D"color:r=
gb(102,102,0)"><</span><span style=3D"color:rgb(102,0,102)">ExpensiveTyp=
e</span><span style=3D"color:rgb(102,102,0)">></span><span> b</span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"color=
:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"color:rgb(=
102,102,0)">(</span><span>a</span><span style=3D"color:rgb(102,102,0)">,</s=
pan><span> b</span><span style=3D"color:rgb(102,102,0)">);</span><span> </s=
pan><span style=3D"color:rgb(102,102,0)">}</span><span><br>
</span><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span><br><br></span><span style=3D"color:rgb(0,0,136)">void</span><span> d=
oubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><span styl=
e=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102=
,102,0)">&&</span><span> a</span><span style=3D"color:rgb(102,102,0=
)">,</span><font color=3D"#000000"><span> </span><span style=3D"color:rgb(1=
02,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)">&&a=
mp;</span><span> b</span><span style=3D"color:rgb(102,102,0)">)</span><span=
> =A0 =A0 =A0 =A0 =A0 =A0</span><span style=3D"color:rgb(102,102,0)">{</spa=
n><span> doSomething</span><span style=3D"color:rgb(102,102,0)">(</span><sp=
an>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>move</span=
><span style=3D"color:rgb(102,102,0)">(</span><span>a</span><span style=3D"=
color:rgb(102,102,0)">),</span><span> std</span><span style=3D"color:rgb(10=
2,102,0)">::</span><span>move</span><span style=3D"color:rgb(102,102,0)">(<=
/span><span>b</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><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#0=
00000"><span style=3D"color:rgb(0,0,136)">const</span><span> </span></font>=
<span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#66=
6600"><span style=3D"color:rgb(102,102,0)">&</span></font><span> a</spa=
n><span style=3D"color:rgb(102,102,0)">,</span><font color=3D"#000000"><spa=
n> </span><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><span st=
yle=3D"color:rgb(102,102,0)">&&</span><span> b</span><span style=3D=
"color:rgb(102,102,0)">)</span><span> =A0 =A0 =A0 </span><span style=3D"col=
or:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"color:rg=
b(102,102,0)">(</span><span>a</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>b</span><span=
style=3D"color:rgb(102,102,0)">));</span><span> </span><span style=3D"colo=
r:rgb(102,102,0)">}</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"co=
lor:rgb(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style=
=3D"color:rgb(102,102,0)">&</span></font><span style=3D"color:rgb(102,1=
02,0)">&</span><span> a</span><span style=3D"color:rgb(102,102,0)">,</s=
pan><span> </span><font color=3D"#000000"><span>=A0</span></font><font colo=
r=3D"#000000"><span style=3D"color:rgb(0,0,136)">const</span><span> </span>=
</font><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=
=3D"#666600"><span style=3D"color:rgb(102,102,0)">&</span></font><font =
color=3D"#000000"><span> b</span><span style=3D"color:rgb(102,102,0)">)</sp=
an><span> =A0 =A0 =A0</span><span style=3D"color:rgb(102,102,0)">{</span><s=
pan> doSomething</span><span style=3D"color:rgb(102,102,0)">(</span><span>s=
td</span><span style=3D"color:rgb(102,102,0)">::</span><span>move</span><sp=
an style=3D"color:rgb(102,102,0)">(</span><span>a</span><span style=3D"colo=
r:rgb(102,102,0)">),</span><span> b</span><span style=3D"color:rgb(102,102,=
0)">);</span><span> </span><span style=3D"color:rgb(102,102,0)">}</span><sp=
an><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#0=
00000"><span style=3D"color:rgb(0,0,136)">const</span><span> </span></font>=
<span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#66=
6600"><span style=3D"color:rgb(102,102,0)">&</span></font><span> a</spa=
n><span style=3D"color:rgb(102,102,0)">,</span><span> </span><font color=3D=
"#000000"><span>=A0</span></font><font color=3D"#000000"><span style=3D"col=
or:rgb(0,0,136)">const</span><span> </span></font><span style=3D"color:rgb(=
102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style=3D"colo=
r:rgb(102,102,0)">&</span></font><font color=3D"#000000"><span> b</span=
><span style=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"=
color:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"color=
:rgb(102,102,0)">(</span><span>a</span><span style=3D"color:rgb(102,102,0)"=
>,</span><span> b</span><span style=3D"color:rgb(102,102,0)">);</span><span=
> </span><span style=3D"color:rgb(102,102,0)">}</span></font><font color=3D=
"#000000"><span><br>
</span></font></div></code></div><br><br><br>Alternative ideas for syntax:<=
div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);backgrou=
nd-color:rgb(250,250,250)"><code><div><font color=3D"#660066"><span style=
=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span><span style=3D"col=
or: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)">in</span><span style=3D"co=
lor:rgb(102,102,0)"><</span><span style=3D"color:rgb(102,0,102)">Expensi=
veType</span><span style=3D"color:rgb(102,102,0)"><u></u>></span><span> =
a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc=
</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#000000"=
><span style=3D"color:rgb(102,102,0)">></span></font><span style=3D"colo=
r:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)">=
<</span><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><sp=
an><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)"><<</s=
pan><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><font color=3D"#666600"><span> sink</span></font=
><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-family:Ari=
al,Helvetica,sans-serif;font-size:13px"><span>sink </span></span><span styl=
e=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#666600" styl=
e=3D"font-family:Arial,Helvetica,sans-serif;font-size:13px"><span> </span><=
/font><span>a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br=
>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><font color=3D"#666600"><span> </span><span styl=
e=3D"color:rgb(0,0,136)">in</span></font><span> a</span><span style=3D"colo=
r:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-family:Ari=
al,Helvetica,sans-serif;font-size:13px"><span style=3D"color:rgb(0,0,136)">=
in</span><span> </span></span><span style=3D"color:rgb(102,0,102)">Expensiv=
eType</span><font color=3D"#666600" style=3D"font-family:Arial,Helvetica,sa=
ns-serif;font-size:13px"><span> </span></font><span>a</span><span style=3D"=
color:rgb(102,102,0)">);</span><span><br>
</span></div></code></div><br><br><br><br></div></div></blockquote></div></=
div></div><span><font color=3D"#888888"><span class=3D"HOEnZb"><font color=
=3D"#888888">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D"_blank">std-pr=
oposals+unsubscribe@isocpp.org</a>.</font></span><div class=3D"im"><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>
</div></font></span></blockquote></div><br></div></div></div><div class=3D"=
HOEnZb"><div class=3D"h5">
<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>
</div></div></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 />
--089e0158b6704fbbec04e6840af3--
.
Author: Xeo <hivemaster@hotmail.de>
Date: Mon, 16 Sep 2013 12:14:33 -0700 (PDT)
Raw View
------=_Part_1490_3385102.1379358873141
Content-Type: text/plain; charset=ISO-8859-1
Not if Richard's NB comment 12
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3733.pdf, search
for "US 12") is properly resolved - which allows copy / move elision from
xvalues.
On Monday, September 16, 2013 8:04:09 PM UTC+2, Billy O'Neal wrote:
>
> You never want "return move(x)" -- it disables RVO.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Mon, Sep 16, 2013 at 10:49 AM, Alex B <deva...@gmail.com <javascript:>>wrote:
>
>> Thinking about it, maybe concepts will be able to (quite elegantly) solve
>> this problem. Consider a Sink concept (rename it to whatever you
>> like/appropriate).
>>
>>
>> template <class T, class U>
>> concept bool Sink()
>> {
>> return is_base_of<T, decay_t<U>>::value;
>> }
>>
>> template <class T>
>> constexpr bool is_mutable_rvalue = !is_const<T>::value &&
>> (is_rvalue_reference<T>::value || !is_reference<T>::value);
>>
>> template <class T>
>> T& make_mutable(const T& t)
>> {
>> return const_cast<T&>(t);
>> }
>>
>>
>> template <Sink<matrix> A, Sink<matrix> B>
>> matrix operator+(A a, B b)
>> {
>> return move(
>> is_mutable_rvalue<A> ? make_mutable(a) += b :
>> is_mutable_rvalue<B> ? make_mutable(b) += a :
>> matrix(a) += b);
>> }
>>
>>
>> On Mon, Sep 16, 2013 at 11:07 AM, Alex B <deva...@gmail.com <javascript:>
>> > wrote:
>>
>>> How do you get a function pointer to one of the four specialization of
>>> doubleSinkFunc?
>>>
>>> Idea of a terse notation sounds nice (sink, in, ...), but if it is a
>>> template, there must at least be a way to declare it using the "template"
>>> keyword, so that we could mark it explicitly that it needs to be
>>> parameterized. And then we could get a pointer to the function taking
>>> "const &" by specifying the parameter with a syntax
>>> like "doubleSinkFunc<const &>". After all, it *is* a template, so we
>>> should be able to mark it and deal with it explicitly.
>>>
>>> On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wrote:
>>>
>>>> Indeed, I think this is not a problem that can be solved with the
>>>> current language features. But it is still a problem that has to be solved.
>>>> In my opinion, the best course of action is having some syntax, that,
>>>> when applied to arguments, makes the compiler generate the 2^n combinations
>>>> of const& and &&.
>>>>
>>>> Instead of introducing new keywords/symbols, why not use *std::sink *as
>>>> a special identifier, similarly to std::initializer_list?
>>>>
>>>> void singleSinkFunc(std::sink<Expen**siveType> a) { doSomething(a); }
>>>> // v--- TRANSLATES TO ---v
>>>>
>>>> void singleSinkFunc(ExpensiveType&& a) { doSomething(std::move(a
>>>> )); }
>>>> void singleSinkFunc(const ExpensiveType& a) { doSomething(a); }
>>>>
>>>> void doubleSinkFunc(std::sink<Expen**siveType> a, std::sink<
>>>> ExpensiveType> b) { doSomething(a, b); }
>>>> // v--- TRANSLATES TO ---v
>>>>
>>>> void doubleSinkFunc(ExpensiveType&& a, ExpensiveType&& b) {doSomething
>>>> (std::move(a), std::move(b)); }
>>>> void doubleSinkFunc(const ExpensiveType& a, ExpensiveType&& b) {doSomething
>>>> (a, std::move(b)); }
>>>> void doubleSinkFunc(ExpensiveType&& a, const ExpensiveType& b) {doSomething
>>>> (std::move(a), b); }
>>>> void doubleSinkFunc(const ExpensiveType& a, const ExpensiveType& b) {doSomething
>>>> (a, b); }
>>>>
>>>>
>>>>
>>>> Alternative ideas for syntax:
>>>>
>>>> void sinkFunc(std::in<ExpensiveType**> a);
>>>> void sinkFunc(>ExpensiveType< a);
>>>> void sinkFunc(ExpensiveType<< a);
>>>> void sinkFunc(ExpensiveType sink a);
>>>> void sinkFunc(sink ExpensiveType a);
>>>> void sinkFunc(ExpensiveType in a);
>>>> void sinkFunc(in ExpensiveType a);
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>
>>> ---
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, send an email to
>>> std-proposal...@isocpp.org <javascript:>.
>>>
>>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> 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/.
------=_Part_1490_3385102.1379358873141
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Not if Richard's NB comment 12 (http://www.open-std.org/jt=
c1/sc22/wg21/docs/papers/2013/n3733.pdf, search for "US 12") is properly re=
solved - which allows copy / move elision from xvalues.<br><br>On Monday, S=
eptember 16, 2013 8:04:09 PM UTC+2, Billy O'Neal wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div>You never want "return move(=
x)" -- it disables RVO.</div></div><div><br clear=3D"all"><div><div dir=3D"=
ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONea=
l/" target=3D"_blank">https://github.com/BillyONeal/</a></div>
<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/<wbr>users/82320/billy-oneal</a></div><di=
v>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Mon, Sep 16, 2013 at 10:49 AM, Alex B=
<span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"fyxCVj5Pxd8J">deva...@gmail.com</a>></span> wrote:<br><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex">
<div dir=3D"ltr">Thinking about it, maybe concepts will be able to (quite e=
legantly) solve this problem. Consider a Sink concept (rename it to whateve=
r you like/appropriate).<div><br><div><br></div><div><div><font face=3D"cou=
rier new, monospace">template <class T, class U></font></div>
<div><font face=3D"courier new, monospace">concept bool Sink()</font></div>=
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace"><span style=3D"white-space:pre-wrap"> </spa=
n>return is_base_of<T, decay_t<U>>::value;</font></div>
<div><font face=3D"courier new, monospace">}</font></div><div><font face=3D=
"courier new, monospace"><br></font></div><div><div><font face=3D"courier n=
ew, monospace">template <class T></font></div><div><font face=3D"cour=
ier new, monospace">constexpr bool is_mutable_rvalue =3D !is_const<T>=
::value && (is_rvalue_reference<T>::value || !is_reference<=
;T>::value);</font></div>
</div><div><font face=3D"courier new, monospace"><br></font></div><div><fon=
t face=3D"courier new, monospace">template <class T></font></div><div=
><font face=3D"courier new, monospace">T& make_mutable(const T& t)<=
/font></div>
<div><font face=3D"courier new, monospace">{</font></div><div><font face=3D=
"courier new, monospace"> return const_cast<T&>(t);</=
font></div><div><font face=3D"courier new, monospace">}</font></div><div><b=
r></div><div>
<font face=3D"courier new, monospace"><br></font></div><div><font face=3D"c=
ourier new, monospace">template <Sink<matrix> A, Sink<matrix>=
; B></font></div><div><font face=3D"courier new, monospace">matrix opera=
tor+(A a, B b)</font></div>
</div><div><font face=3D"courier new, monospace">{</font></div><div><font f=
ace=3D"courier new, monospace"> return move(</font></div><div><=
font face=3D"courier new, monospace"> </font><span=
style=3D"font-family:"courier new",monospace">is_mutable_rvalue<=
/span><font face=3D"courier new, monospace"><A> ? make_mutable(a) +=
=3D b :</font></div>
<div><font face=3D"courier new, monospace"> </font=
><span style=3D"font-family:"courier new",monospace">is_mutable_r=
value</span><font face=3D"courier new, monospace"><B> ? make_mutable(=
b) +=3D a :</font></div>
<div>
<font face=3D"courier new, monospace"> matrix(a) +=3D b=
);</font></div><div><font face=3D"courier new, monospace">}</font></div><di=
v><br></div><div><br><div class=3D"gmail_quote"><div>
<div>On Mon, Sep 16, 2013 at 11:07 AM, Alex B <span dir=3D"ltr"><<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"fyxCVj5Pxd8J">d=
eva...@gmail.com</a>></span> wrote:<br>
</div></div><blockquote class=3D"gmail_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"><div><div><div dir=3D"ltr"><div>How do you get=
a function pointer to one of the four specialization of doubleSinkFunc?</d=
iv>
<div> </div><div>Idea of a terse notation sounds nice (sink, in, ...),=
but if it is a template, there must at least be a way to declare it using =
the "template" keyword, so that we could mark it explicitly that it needs t=
o be parameterized. And then we could get a pointer to the function taking =
"const &" by specifying the parameter with a syntax like "dou=
bleSinkFunc<const &>". After all, it <i>is</i> a template, so we =
should be able to mark it and deal with it explicitly.</div>
<div><br>On Monday, September 16, 2013 6:20:37 AM UTC-4, Vittorio Romeo wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px=
;border-left-style:solid">
<div dir=3D"ltr">Indeed, I think this is not a problem that can be solved w=
ith the current language features. But it is still a problem that has to be=
solved.<br>In my opinion, the best course of action is having some syntax,=
that, when applied to arguments, makes the compiler generate the 2^n combi=
nations of const& and &&.<br>
<br>Instead of introducing new keywords/symbols, why not use <b>std::sink <=
/b>as a special identifier, similarly to std::initializer_list?<br><br><div=
style=3D"border:1px solid rgb(187,187,187);background-color:rgb(250,250,25=
0)">
<code><div><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"#00=
0000"><span> singleSinkFunc</span></font><span style=3D"color:rgb(102,102,0=
)">(</span><span>std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan>sink</span><span style=3D"color:rgb(102,102,0)"><</span><span style=
=3D"color:rgb(102,0,102)">Expen<u></u><wbr>siveType</span><span style=3D"co=
lor:rgb(102,102,0)">></span><font color=3D"#000000"><span> a</span><span=
style=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D"color:=
rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"color:rgb(1=
02,102,0)">(</span><span>a</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><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span><br><br></span></font><span style=3D"color:rgb(0,0,136)">void</span><=
font color=3D"#000000"><span> singleSinkFunc</span></font><span style=3D"co=
lor:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)">ExpensiveT=
ype</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&=
;&</span></font><font color=3D"#000000"><span> a</span><span style=3D"c=
olor:rgb(102,102,0)">)</span><span> </span><span style=
=3D"color:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"c=
olor: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)">(</sp=
an><span>a</span><span style=3D"color:rgb(102,102,0)">));</span><span> </sp=
an><span style=3D"color:rgb(102,102,0)">}</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><font color=3D"=
#000000"><span> singleSinkFunc</span></font><span style=3D"color:rgb(102,10=
2,0)">(</span><font color=3D"#000000"><span style=3D"color:rgb(0,0,136)">co=
nst</span><span> </span></font><span style=3D"color:rgb(102,0,102)">Expensi=
veType</span><font color=3D"#666600"><span style=3D"color:rgb(102,102,0)">&=
amp;</span></font><font color=3D"#000000"><span> a</span><span style=3D"col=
or:rgb(102,102,0)">)</span><span> </span><span style=3D"color:rgb(102,102,0=
)">{</span><span> doSomething</span><span style=3D"color:rgb(102,102,0)">(<=
/span><span>a</span><span style=3D"color:rgb(102,102,0)">);</span><span> </=
span><span style=3D"color:rgb(102,102,0)">}</span></font></div>
</code></div><br><div style=3D"border:1px solid rgb(187,187,187);background=
-color:rgb(250,250,250)"><code><div><font color=3D"#660066"><span style=3D"=
color:rgb(0,0,136)">void</span><span> doubleSinkFunc</span><span style=3D"c=
olor:rgb(102,102,0)">(</span><span>std</span><span style=3D"color:rgb(102,1=
02,0)">::</span><span>sink</span><span style=3D"color:rgb(102,102,0)"><<=
/span><span style=3D"color:rgb(102,0,102)">Expen<u></u><wbr>siveType</span>=
<span style=3D"color:rgb(102,102,0)">></span><span> a</span><span style=
=3D"color:rgb(102,102,0)">,</span><span> </span></font><span>std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span>sink</span><span style=3D"c=
olor:rgb(102,102,0)"><</span><span style=3D"color:rgb(102,0,102)">Expens=
iveType</span><span style=3D"color:rgb(102,102,0)">></span><span> b</spa=
n><span style=3D"color:rgb(102,102,0)">)</span><span> </span><span style=3D=
"color:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"colo=
r:rgb(102,102,0)">(</span><span>a</span><span style=3D"color:rgb(102,102,0)=
">,</span><span> b</span><span style=3D"color:rgb(102,102,0)">);</span><spa=
n> </span><span style=3D"color:rgb(102,102,0)">}</span><span><br>
</span><span style=3D"color:rgb(136,0,0)">// v--- TRANSLATES TO ---v</span>=
<span><br><br></span><span style=3D"color:rgb(0,0,136)">void</span><span> d=
oubleSinkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><span styl=
e=3D"color:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102=
,102,0)">&&</span><span> a</span><span style=3D"color:rgb(102,102,0=
)">,</span><font color=3D"#000000"><span> </span><span style=3D"color:rgb(1=
02,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)">&&a=
mp;</span><span> b</span><span style=3D"color:rgb(102,102,0)">)</span><span=
> </span><span style=3D"color:rgb(=
102,102,0)">{</span><span> doSomething</span><span style=3D"color:rgb(102,1=
02,0)">(</span><span>std</span><span style=3D"color:rgb(102,102,0)">::</spa=
n><span>move</span><span style=3D"color:rgb(102,102,0)">(</span><span>a</sp=
an><span style=3D"color:rgb(102,102,0)">),</span><span> std</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span>move</span><span style=3D"color:=
rgb(102,102,0)">(</span><span>b</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><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#0=
00000"><span style=3D"color:rgb(0,0,136)">const</span><span> </span></font>=
<span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#66=
6600"><span style=3D"color:rgb(102,102,0)">&</span></font><span> a</spa=
n><span style=3D"color:rgb(102,102,0)">,</span><font color=3D"#000000"><spa=
n> </span><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><span st=
yle=3D"color:rgb(102,102,0)">&&</span><span> b</span><span style=3D=
"color:rgb(102,102,0)">)</span><span> </span><span sty=
le=3D"color:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D=
"color:rgb(102,102,0)">(</span><span>a</span><span style=3D"color:rgb(102,1=
02,0)">,</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</sp=
an><span>move</span><span style=3D"color:rgb(102,102,0)">(</span><span>b</s=
pan><span style=3D"color:rgb(102,102,0)">));</span><span> </span><span styl=
e=3D"color:rgb(102,102,0)">}</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"co=
lor:rgb(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style=
=3D"color:rgb(102,102,0)">&</span></font><span style=3D"color:rgb(102,1=
02,0)">&</span><span> a</span><span style=3D"color:rgb(102,102,0)">,</s=
pan><span> </span><font color=3D"#000000"><span> </span></font><font c=
olor=3D"#000000"><span style=3D"color:rgb(0,0,136)">const</span><span> </sp=
an></font><span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font co=
lor=3D"#666600"><span style=3D"color:rgb(102,102,0)">&</span></font><fo=
nt color=3D"#000000"><span> b</span><span style=3D"color:rgb(102,102,0)">)<=
/span><span> </span><span style=3D"color:rgb(102,102,0)=
">{</span><span> doSomething</span><span style=3D"color:rgb(102,102,0)">(</=
span><span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>mo=
ve</span><span style=3D"color:rgb(102,102,0)">(</span><span>a</span><span s=
tyle=3D"color:rgb(102,102,0)">),</span><span> b</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><span style=3D"color:rgb(0,0,136)">void</span><span> doubleSi=
nkFunc</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#0=
00000"><span style=3D"color:rgb(0,0,136)">const</span><span> </span></font>=
<span style=3D"color:rgb(102,0,102)">ExpensiveType</span><font color=3D"#66=
6600"><span style=3D"color:rgb(102,102,0)">&</span></font><span> a</spa=
n><span style=3D"color:rgb(102,102,0)">,</span><span> </span><font color=3D=
"#000000"><span> </span></font><font color=3D"#000000"><span style=3D"=
color:rgb(0,0,136)">const</span><span> </span></font><span style=3D"color:r=
gb(102,0,102)">ExpensiveType</span><font color=3D"#666600"><span style=3D"c=
olor:rgb(102,102,0)">&</span></font><font color=3D"#000000"><span> b</s=
pan><span style=3D"color:rgb(102,102,0)">)</span><span> </span><span style=
=3D"color:rgb(102,102,0)">{</span><span> doSomething</span><span style=3D"c=
olor:rgb(102,102,0)">(</span><span>a</span><span style=3D"color:rgb(102,102=
,0)">,</span><span> b</span><span style=3D"color:rgb(102,102,0)">);</span><=
span> </span><span style=3D"color:rgb(102,102,0)">}</span></font><font colo=
r=3D"#000000"><span><br>
</span></font></div></code></div><br><br><br>Alternative ideas for syntax:<=
div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);backgrou=
nd-color:rgb(250,250,250)"><code><div><font color=3D"#660066"><span style=
=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span><span style=3D"col=
or: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)">in</span><span style=3D"co=
lor:rgb(102,102,0)"><</span><span style=3D"color:rgb(102,0,102)">Expensi=
veType</span><span style=3D"color:rgb(102,102,0)"><u></u><wbr>></span><s=
pan> a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span></font><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc=
</span><span style=3D"color:rgb(102,102,0)">(</span><font color=3D"#000000"=
><span style=3D"color:rgb(102,102,0)">></span></font><span style=3D"colo=
r:rgb(102,0,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)">=
<</span><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><sp=
an><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><span style=3D"color:rgb(102,102,0)"><<</s=
pan><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><font color=3D"#666600"><span> sink</span></font=
><span> a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-family:Ari=
al,Helvetica,sans-serif;font-size:13px"><span>sink </span></span><span styl=
e=3D"color:rgb(102,0,102)">ExpensiveType</span><font style=3D"font-family:A=
rial,Helvetica,sans-serif;font-size:13px" color=3D"#666600"><span> </span><=
/font><span>a</span><span style=3D"color:rgb(102,102,0)">);</span><span><br=
>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0=
,102)">ExpensiveType</span><font color=3D"#666600"><span> </span><span styl=
e=3D"color:rgb(0,0,136)">in</span></font><span> a</span><span style=3D"colo=
r:rgb(102,102,0)">);</span><span><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span> sinkFunc</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"font-family:Ari=
al,Helvetica,sans-serif;font-size:13px"><span style=3D"color:rgb(0,0,136)">=
in</span><span> </span></span><span style=3D"color:rgb(102,0,102)">Expensiv=
eType</span><font style=3D"font-family:Arial,Helvetica,sans-serif;font-size=
:13px" color=3D"#666600"><span> </span></font><span>a</span><span style=3D"=
color:rgb(102,102,0)">);</span><span><br>
</span></div></code></div><br><br><br><br></div></div></blockquote></div></=
div></div><span><font color=3D"#888888"><span><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/flqtAYA-yMI/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/f=
lqtAYA-yMI/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"fyxCVj5Pxd8J">s=
td-proposal...@<wbr>isocpp.org</a>.</font></span><div><br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"fyxCVj5Pxd8J">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></font></span></blockquote></div><br></div></div></div><div><div>
<p></p>
-- <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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
fyxCVj5Pxd8J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"fyxCVj5Pxd8J">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></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_1490_3385102.1379358873141--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Mon, 16 Sep 2013 12:59:37 -0700 (PDT)
Raw View
------=_Part_243_9201122.1379361577186
Content-Type: text/plain; charset=ISO-8859-1
@1 Striving for strong exception safety is a noble goal in general but in
the example I showed it seems unnecessary and imposes overhead. What
user-visible state are you trying to keep safe from exceptions? The
initiaizer_list does not live too long before and after the function it is
invoked for. The initializer_list could contain lvalues and those should be
protected from exceptions. I do that by making a copy only if there is an
lvalue. If an element is rvalue then by definition no one else has seen it
and therefore I move from it. Now any exception down the line will free the
result vector invoking destructors on the copies of lvalues and the moved
from rvalues. The lvalues that the iteration never reached to will remain
unchanged. Everything is still exception safe without the overhead of
copying all the initializer_list elements upfront and thereby loosing the
opportunities to move.
@2 That's right, I want to return a new vector every time.
@3 The moves are necessary in the code I've shown. operator += returns
matrix & and must be converted to matrix &&. emplace_back won't do any
magic in this case, IMO.
Finally, on the main subject: I'm not sure since when std::initializer_list
has become a niche. Does the standard say that? It is less common than
writing a constructor, I agree but more likely than a overleaded binary
operator.
And here is the benchmark routine. For the record, I don't benchmark with
I/O enabled.
void invoke_binary(int iter)
{
matrix s1, s2;
for(int i=0;i < iter; ++i)
{
int branch = rand() % 4;
switch(branch)
{
case 0: {
matrix m1 (matrix() + s1);
break;
}
case 1: {
matrix m2 (matrix() + matrix());
break;
}
case 2: {
matrix m3 (s1 + s2);
break;
}
case 3: {
matrix m4 (s1 + matrix());
break;
}
}
}
}
On Monday, September 16, 2013 9:15:17 AM UTC-7, Billy O'Neal wrote:
>
> Can you post the benchmark code? Not that I don't trust you, but 1-2% is
> well within the margin of error in most cases. In particular, any time you
> involve IO (e.g. std::cout) that's going to play havoc with benchmarks.
>
> Regarding your code example, that API is poor for 2 reasons:
> 1. doing in a way that is exception safe is impossible. The way to make it
> exception safe is just to make copies.
> 2. that interface forces creation of a new vector on every call.
> 3. you have way too many unnecessary moves in that example -- use emplace
> where possible. If T was something like std::array, move is not cheaper
> than copy.
>
> You can fix (1) using something like:
> // Note: I'm no initializer_list expert -- you may need to
> // have some kind of wrapper type if it isn't legal to take
> // a const&.
> std::vector<matrix>
> add_scalar(std::initializer_list<matrix const&> matrices,
> std::initializer_list<int> scalars)
> {
> if(matrices.size() != scalars.size()) {
> assert(false && "Matrix scalar size mismatch!");
> std::terminate(); // Don't throw for things that should terminate!
> }
>
> // Make exception safe copy:
> std::vector<matrix> result(begin(matricies), end(matricies));
> auto si = begin(scalars); // Nothrow
> for(matrix& m : result) // Norhrow
> {
> m += *si++; // Nothrow
> }
>
> return result;
> }
>
> Most importantly though, this is a niche case, not a common case. The
> original proposal was trying to support the common case of having a
> constructor with a sink argument. That is a compelling reason to add things
> to the standard -- I'm not sure this is, even in the couple of places where
> it may make sense..
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Sun, Sep 15, 2013 at 4:48 PM, Sumant Tambe <sut...@gmail.com<javascript:>
> > wrote:
>
>> Thanks for the detailed analysis. I agree that in<T> is slightly better
>> in some cases and slightly inferior in others. I ran a benchmark and saw
>> about 1-2% improvement in performance when using in<T> as opposed to the
>> example #2 you proposed. Each run of the benchmark executed all 4 versions
>> (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of binary
>> operator+ with equal probability (rand() % 4).
>>
>> 1 to 2 % performance gain may or may not be "worth" it. People should use
>> their judgement. However, story does not end here.
>>
>> Binary operator +() provides only one opportunity for in<T> to save a
>> copy. I.e., when the right hand side object is an rvalue. The in<T> idiom
>> shines the most when there are more opportunities to detect rvalues and to
>> exploit them at run-time. So here is a small function to add scalars to a
>> list of matrices.
>>
>> std::vector<matrix>
>> add_scalar(std::initializer_list<in<matrix>> matrices,
>> std::initializer_list<int> scalars)
>> {
>> if(matrices.size() != scalars.size())
>> throw 0;
>>
>> std::vector<matrix> result;
>> result.reserve(matrices.size());
>>
>> auto si = begin(scalars);
>> for(const in<matrix> & m : matrices)
>> {
>> if(m.rvalue()) {
>> cout << "rvalue matrix\n";
>> result.push_back(std::move(m.rget() += *si));
>> }
>> else {
>> cout << "lvalue matrix\n";
>> result.push_back(std::move(matrix(m) += *si));
>> }
>> }
>>
>> return result;
>> }
>>
>> And I call it like this:
>>
>> matrix s1, s2, s3, s4;
>> add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
>>
>> I tested this code on g++ 4.9 and clang 3.3.
>>
>> In each use, this function gives finite but unknown number of
>> opportunities to exploit move-semantics. I'm not sure if such a function
>> can be easily implemented using universal references. Variadic templates
>> come to mind but two lists of parameters probably requires separate
>> grouping. I guess it could be done using std::tuple and two variadic
>> parameter packs of universal references. But std::make_tuple is not as
>> pretty as std::initializer_list.
>>
>> Surprisingly, in<T> works nicely with initializer_list<T>.
>> Initilizer_list does not appear to retain rvalue/lvalue-ness of the
>> original parameter because initializer_list iterator is a pointer to
>> consts. In<T>, however, allows the rvalue/lvalue knowledge of the original
>> parameter pass through the initializer_list--here is the best part--without
>> subverting const-correctness. All member functions in in<T> are const.
>>
>> Thoughts?
>>
>> Sumant
>>
>> --
>>
>> ---
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> 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/.
------=_Part_243_9201122.1379361577186
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">@1 Striving for strong exception safety is a noble goal in=
general but in the example I showed it seems unnecessary and imposes overh=
ead. What user-visible state are you trying to keep safe from exceptions? T=
he initiaizer_list does not live too long before and after the function it =
is invoked for. The initializer_list could contain lvalues and those should=
be protected from exceptions. I do that by making a copy only if there is =
an lvalue. If an element is rvalue then by definition no one else has seen =
it and therefore I move from it. Now any exception down the line will free =
the result vector invoking destructors on the copies of lvalues and the mov=
ed from rvalues. The lvalues that the iteration never reached to will remai=
n unchanged. Everything is still exception safe without the overhead of cop=
ying all the initializer_list elements upfront and thereby loosing the oppo=
rtunities to move.<div>@2 That's right, I want to return a new vector every=
time.<br></div><div>@3 The moves are necessary in the code I've shown. ope=
rator +=3D returns matrix & and must be converted to matrix &&.=
emplace_back won't do any magic in this case, IMO.<br></div><div><br></div=
><div>Finally, on the main subject: I'm not sure since when std::initialize=
r_list has become a niche. Does the standard say that? It is less common th=
an writing a constructor, I agree but more likely than a overleaded binary =
operator.</div><div><br></div><div>And here is the benchmark routine. For t=
he record, I don't benchmark with I/O enabled.</div><div><div>void invoke_b=
inary(int iter)</div><div>{</div><div> matrix s1, s2;</div><div> =
; for(int i=3D0;i < iter; ++i)</div><div> {</div><div>  =
; int branch =3D rand() % 4;</div><div> switch(branch)</div><d=
iv> {</div><div> case 0: {</div><div> =
; matrix m1 (matrix() + s1);</div><div> &=
nbsp; break;</div><div> }</div><div>  =
; case 1: {</div><div> matrix m2 (matrix(=
) + matrix());</div><div> break;</div><div> =
; }</div><div> case 2: {</div><div> =
matrix m3 (s1 + s2);</div><div> &=
nbsp; break;</div><div> }</div><div>  =
; case 3: {</div><div> matrix m4 (s1 + matrix())=
;</div><div> break;</div><div> &nbs=
p; }</div><div> } </div><div> }</div><div>}=
</div></div><div><br>On Monday, September 16, 2013 9:15:17 AM UTC-7, Billy =
O'Neal wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>Can you post the benchmark code? Not that I don't trust you, but 1-2% =
is well within the margin of error in most cases. In particular, any time y=
ou involve IO (e.g. std::cout) that's going to play havoc with benchmarks.<=
/div>
<div> </div><div>Regarding your code example, that API is poor for 2 r=
easons:</div><div>1. doing in a way that is exception safe is impossible. T=
he way to make it exception safe is just to make copies.</div><div>2. that =
interface forces creation of a new vector on every call.</div>
<div>3. you have way too many unnecessary moves in that example -- use empl=
ace where possible. If T was something like std::array, move is not cheaper=
than copy.</div><div><div> </div><div>You can fix (1) using something=
like:</div>
<div>// Note: I'm no initializer_list expert -- you may need to<br>// have =
some kind of wrapper type if it isn't legal to take<br>// a const&.<br>=
std::vector<matrix><br>add_scalar(std::initializer_<wbr>list<matri=
x const&> matrices,<br>
std::initializ=
er_list<int> scalars)<br>{<br> if(matrices.size() !=3D scalars.=
size()) {<br> assert(false && "Matrix scalar size=
mismatch!");<br> std::terminate(); // Don't throw for th=
ings that should terminate!<br>
}<br> <br> // Make exception safe copy:<br> std::v=
ector<matrix> result(begin(matricies), end(matricies));<br> aut=
o si =3D begin(scalars); // Nothrow<br> for(matrix& m : result) /=
/ Norhrow<br> {<br> m +=3D *si++; // Nothrow<=
br>
}<br> <br> return result;<br>}</div></div><div> </d=
iv><div>Most importantly though, this is a niche case, not a common case. T=
he original proposal was trying to support the common case of having a cons=
tructor with a sink argument. That is a compelling reason to add things to =
the standard -- I'm not sure this is, even in the couple of places where it=
may make sense..</div>
</div><div><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/u=
sers/82320/billy-oneal" target=3D"_blank">http://stackoverflow.com/<wbr>use=
rs/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Sun, Sep 15, 2013 at 4:48 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-o=
bfuscated-mailto=3D"IbIyJAd1r8QJ">sut...@gmail.com</a>></span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4). =
<br>
</div><div><br></div><div>1 to 2 % performance gain may or may not be "wort=
h" it. People should use their judgement. However, story does not end here.=
</div><div><br></div><div>Binary operator +() provides only one opportunity=
for in<T> to save a copy. I.e., when the right hand side objec=
t is an rvalue. The in<T> idiom shines the most when there are more o=
pportunities to detect rvalues and to exploit them at run-time. So here is =
a small function to add scalars to a list of matrices. </div>
<div><br></div><div><div>std::vector<matrix></div><div>add_scalar(std=
::initializer_<wbr>list<in<matrix>> matrices,</div><div> =
std::initializer_list<int> scalars)=
</div><div>{</div><div> if(matrices.size() !=3D scalars.size())</div>
<div> throw 0;</div><div><br></div><div> std::vector<=
matrix> result;</div><div> result.reserve(matrices.size()<wbr>);</=
div><div> </div><div> auto si =3D begin(scalars);</div><di=
v> for(const in<matrix> & m : matrices)</div>
<div> {</div><div> if(m.rvalue()) {</div><div>&nbs=
p; cout << "rvalue matrix\n";</div><div> &=
nbsp; result.push_back(std::move(m.<wbr>rget() +=3D *si));</d=
iv><div> }</div><div> else {</div><di=
v> cout << "lvalue matrix\n";</div>
<div> result.push_back(std::move(<wbr>matrix(m) =
+=3D *si));</div><div> }</div><div> }</div><div><b=
r></div><div> return result;</div><div>}</div><div><br></div><div>And=
I call it like this:</div><div><div><br></div>
<div>
matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { =
3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g++ 4.9 =
and clang 3.3.</div><div><br></div><div>In each use, this function gives fi=
nite but unknown number of opportunities to exploit move-semantics. I'm not=
sure if such a function can be easily implemented using universal referenc=
es. Variadic templates come to mind but two lists of parameters probably re=
quires separate grouping. I guess it could be done using std::tuple and two=
variadic parameter packs of universal references. But std::make_tuple is n=
ot as pretty as std::initializer_list.</div>
<div><br></div><div>Surprisingly, in<T> works nicely with initializer=
_list<T>. Initilizer_list does not appear to retain rvalue/lvalue-nes=
s of the original parameter because initializer_list iterator is a pointer =
to consts. In<T>, however, allows the rvalue/lvalue knowledge of the =
original parameter pass through the initializer_list--here is the best part=
--without subverting const-correctness. All member functions in in<T>=
are const. </div>
<div><br></div><div>Thoughts?</div><span><font color=3D"#888888"><div><br><=
/div><div>Sumant</div><br></font></span></div></div><div><div>
<p></p>
-- <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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
IbIyJAd1r8QJ">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"IbIyJAd1r8QJ">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></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_243_9201122.1379361577186--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Mon, 16 Sep 2013 13:24:00 -0700
Raw View
--047d7b5d452c71135504e685feaa
Content-Type: text/plain; charset=ISO-8859-1
1. Then I guess we just fundamentally disagree. Just because something is
an rvalue at one point does not mean that it will stay that way if an
exception is thrown. For instance, if the matrices come out of a vector
with move() applied to the vector's elements. But if an exception is
thrown, the caller probably doesn't want the vector to have been modified.
2. Ok, well that sucks for performance. Making the micro-optimization of
being able to move in some cases is probably completely overshadowed by
having to create new vectors every time for that particular call.
3. No, the moves are not necessary. Emplace them into the vector, and then
apply += in their new positions. (As I demonstrated in my example)
4. That benchmark is flawed. On different runs you're executing completely
different operations. Not to mention I would be hugely surprised if any
compiler didn't just inline the whole thing and defeat the benchmark.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Mon, Sep 16, 2013 at 12:59 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> @1 Striving for strong exception safety is a noble goal in general but in
> the example I showed it seems unnecessary and imposes overhead. What
> user-visible state are you trying to keep safe from exceptions? The
> initiaizer_list does not live too long before and after the function it is
> invoked for. The initializer_list could contain lvalues and those should be
> protected from exceptions. I do that by making a copy only if there is an
> lvalue. If an element is rvalue then by definition no one else has seen it
> and therefore I move from it. Now any exception down the line will free the
> result vector invoking destructors on the copies of lvalues and the moved
> from rvalues. The lvalues that the iteration never reached to will remain
> unchanged. Everything is still exception safe without the overhead of
> copying all the initializer_list elements upfront and thereby loosing the
> opportunities to move.
> @2 That's right, I want to return a new vector every time.
> @3 The moves are necessary in the code I've shown. operator += returns
> matrix & and must be converted to matrix &&. emplace_back won't do any
> magic in this case, IMO.
>
> Finally, on the main subject: I'm not sure since when
> std::initializer_list has become a niche. Does the standard say that? It is
> less common than writing a constructor, I agree but more likely than a
> overleaded binary operator.
>
> And here is the benchmark routine. For the record, I don't benchmark with
> I/O enabled.
> void invoke_binary(int iter)
> {
> matrix s1, s2;
> for(int i=0;i < iter; ++i)
> {
> int branch = rand() % 4;
> switch(branch)
> {
> case 0: {
> matrix m1 (matrix() + s1);
> break;
> }
> case 1: {
> matrix m2 (matrix() + matrix());
> break;
> }
> case 2: {
> matrix m3 (s1 + s2);
> break;
> }
> case 3: {
> matrix m4 (s1 + matrix());
> break;
> }
> }
> }
> }
>
> On Monday, September 16, 2013 9:15:17 AM UTC-7, Billy O'Neal wrote:
>
>> Can you post the benchmark code? Not that I don't trust you, but 1-2% is
>> well within the margin of error in most cases. In particular, any time you
>> involve IO (e.g. std::cout) that's going to play havoc with benchmarks.
>>
>> Regarding your code example, that API is poor for 2 reasons:
>> 1. doing in a way that is exception safe is impossible. The way to make
>> it exception safe is just to make copies.
>> 2. that interface forces creation of a new vector on every call.
>> 3. you have way too many unnecessary moves in that example -- use emplace
>> where possible. If T was something like std::array, move is not cheaper
>> than copy.
>>
>> You can fix (1) using something like:
>> // Note: I'm no initializer_list expert -- you may need to
>> // have some kind of wrapper type if it isn't legal to take
>> // a const&.
>> std::vector<matrix>
>> add_scalar(std::initializer_**list<matrix const&> matrices,
>> std::initializer_list<int> scalars)
>> {
>> if(matrices.size() != scalars.size()) {
>> assert(false && "Matrix scalar size mismatch!");
>> std::terminate(); // Don't throw for things that should terminate!
>> }
>>
>> // Make exception safe copy:
>> std::vector<matrix> result(begin(matricies), end(matricies));
>> auto si = begin(scalars); // Nothrow
>> for(matrix& m : result) // Norhrow
>> {
>> m += *si++; // Nothrow
>> }
>>
>> return result;
>> }
>>
>> Most importantly though, this is a niche case, not a common case. The
>> original proposal was trying to support the common case of having a
>> constructor with a sink argument. That is a compelling reason to add things
>> to the standard -- I'm not sure this is, even in the couple of places where
>> it may make sense..
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>> Malware Response Instructor - BleepingComputer.com
>>
>>
>> On Sun, Sep 15, 2013 at 4:48 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>
>>> Thanks for the detailed analysis. I agree that in<T> is slightly
>>> better in some cases and slightly inferior in others. I ran a benchmark and
>>> saw about 1-2% improvement in performance when using in<T> as opposed to
>>> the example #2 you proposed. Each run of the benchmark executed all 4
>>> versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of
>>> binary operator+ with equal probability (rand() % 4).
>>>
>>> 1 to 2 % performance gain may or may not be "worth" it. People should
>>> use their judgement. However, story does not end here.
>>>
>>> Binary operator +() provides only one opportunity for in<T> to save a
>>> copy. I.e., when the right hand side object is an rvalue. The in<T> idiom
>>> shines the most when there are more opportunities to detect rvalues and to
>>> exploit them at run-time. So here is a small function to add scalars to a
>>> list of matrices.
>>>
>>> std::vector<matrix>
>>> add_scalar(std::initializer_**list<in<matrix>> matrices,
>>> std::initializer_list<int> scalars)
>>> {
>>> if(matrices.size() != scalars.size())
>>> throw 0;
>>>
>>> std::vector<matrix> result;
>>> result.reserve(matrices.size()**);
>>>
>>> auto si = begin(scalars);
>>> for(const in<matrix> & m : matrices)
>>> {
>>> if(m.rvalue()) {
>>> cout << "rvalue matrix\n";
>>> result.push_back(std::move(m.**rget() += *si));
>>> }
>>> else {
>>> cout << "lvalue matrix\n";
>>> result.push_back(std::move(**matrix(m) += *si));
>>> }
>>> }
>>>
>>> return result;
>>> }
>>>
>>> And I call it like this:
>>>
>>> matrix s1, s2, s3, s4;
>>> add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
>>>
>>> I tested this code on g++ 4.9 and clang 3.3.
>>>
>>> In each use, this function gives finite but unknown number of
>>> opportunities to exploit move-semantics. I'm not sure if such a function
>>> can be easily implemented using universal references. Variadic templates
>>> come to mind but two lists of parameters probably requires separate
>>> grouping. I guess it could be done using std::tuple and two variadic
>>> parameter packs of universal references. But std::make_tuple is not as
>>> pretty as std::initializer_list.
>>>
>>> Surprisingly, in<T> works nicely with initializer_list<T>.
>>> Initilizer_list does not appear to retain rvalue/lvalue-ness of the
>>> original parameter because initializer_list iterator is a pointer to
>>> consts. In<T>, however, allows the rvalue/lvalue knowledge of the original
>>> parameter pass through the initializer_list--here is the best part--without
>>> subverting const-correctness. All member functions in in<T> are const.
>>>
>>> Thoughts?
>>>
>>> Sumant
>>>
>>> --
>>>
>>> ---
>>> 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-proposal...@**isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>>
>>> Visit this group at http://groups.google.com/a/**isocpp.org/group/std-**
>>> proposals/ <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/.
>
--
---
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/.
--047d7b5d452c71135504e685feaa
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>1. Then I guess we just fundamentally disagree. Just =
because something is an rvalue at one point does not mean that it will stay=
that way if an exception is thrown. For instance, if the matrices come out=
of a vector with move() applied to the vector's elements. But if an ex=
ception is thrown, the caller probably doesn't want the vector to have =
been modified.</div>
<div>2. Ok, well that sucks for performance. Making the micro-optimization =
of being able to move in some cases is probably completely overshadowed by =
having to create new vectors every time for that particular call.</div>
<div>3. No, the moves are not necessary. Emplace them into the vector, and =
then apply +=3D in their new positions. (As I demonstrated in my example)</=
div><div>4.=A0That benchmark is flawed. On different runs you're execut=
ing completely different operations. Not to mention I would be hugely surpr=
ised if any compiler didn't just inline the whole thing and defeat the =
benchmark.</div>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>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://=
stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Mon, Sep 16, 2013 at 12:59 PM, Sumant=
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D=
"_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
<div dir=3D"ltr">@1 Striving for strong exception safety is a noble goal in=
general but in the example I showed it seems unnecessary and imposes overh=
ead. What user-visible state are you trying to keep safe from exceptions? T=
he initiaizer_list does not live too long before and after the function it =
is invoked for. The initializer_list could contain lvalues and those should=
be protected from exceptions. I do that by making a copy only if there is =
an lvalue. If an element is rvalue then by definition no one else has seen =
it and therefore I move from it. Now any exception down the line will free =
the result vector invoking destructors on the copies of lvalues and the mov=
ed from rvalues. The lvalues that the iteration never reached to will remai=
n unchanged. Everything is still exception safe without the overhead of cop=
ying all the initializer_list elements upfront and thereby loosing the oppo=
rtunities to move.<div>
@2 That's right, I want to return a new vector every time.<br></div><di=
v>@3 The moves are necessary in the code I've shown. operator +=3D retu=
rns matrix & and must be converted to matrix &&. emplace_back w=
on't do any magic in this case, IMO.<br>
</div><div><br></div><div>Finally, on the main subject: I'm not sure si=
nce when std::initializer_list has become a niche. Does the standard say th=
at? It is less common than writing a constructor, I agree but more likely t=
han a overleaded binary operator.</div>
<div><br></div><div>And here is the benchmark routine. For the record, I do=
n't benchmark with I/O enabled.</div><div><div>void invoke_binary(int i=
ter)</div><div>{</div><div>=A0 matrix s1, s2;</div><div>=A0 for(int i=3D0;i=
< iter; ++i)</div>
<div>=A0 {</div><div>=A0 =A0 int branch =3D rand() % 4;</div><div>=A0 =A0 s=
witch(branch)</div><div>=A0 =A0 {</div><div>=A0 =A0 =A0 case 0: {</div><div=
class=3D"im"><div>=A0 =A0 =A0 =A0 matrix m1 (matrix() + s1);</div></div><d=
iv>=A0 =A0 =A0 =A0 break;</div><div>
=A0 =A0 =A0 }</div><div>=A0 =A0 =A0 case 1: {</div><div class=3D"im"><div>=
=A0 =A0 =A0 =A0 matrix m2 (matrix() + matrix());</div></div><div>=A0 =A0 =
=A0 =A0 break;</div><div>=A0 =A0 =A0 }</div><div>=A0 =A0 =A0 case 2: {</div=
><div class=3D"im"><div>=A0 =A0 =A0 =A0 matrix m3 (s1 + s2);</div>
</div><div>=A0 =A0 =A0 =A0 break;</div><div>=A0 =A0 =A0 }</div><div>=A0 =A0=
=A0 case 3: {</div><div class=3D"im"><div>=A0 =A0 =A0 =A0 matrix m4 (s1 + =
matrix());</div></div><div>=A0 =A0 =A0 =A0 break;</div><div>=A0 =A0 =A0 }</=
div><div>=A0 =A0 } =A0 =A0</div><div>=A0 }</div><div>
}</div></div><div><div><div class=3D"h5"><br>On Monday, September 16, 2013 =
9:15:17 AM UTC-7, Billy O'Neal wrote:</div></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">
<div><div class=3D"h5"><div dir=3D"ltr"><div>Can you post the benchmark cod=
e? Not that I don't trust you, but 1-2% is well within the margin of er=
ror in most cases. In particular, any time you involve IO (e.g. std::cout) =
that's going to play havoc with benchmarks.</div>
<div>=A0</div><div>Regarding your code example, that API is poor for 2 reas=
ons:</div><div>1. doing in a way that is exception safe is impossible. The =
way to make it exception safe is just to make copies.</div><div>2. that int=
erface forces creation of a new vector on every call.</div>
<div>3. you have way too many unnecessary moves in that example -- use empl=
ace where possible. If T was something like std::array, move is not cheaper=
than copy.</div><div><div>=A0</div><div>You can fix (1) using something li=
ke:</div>
<div>// Note: I'm no initializer_list expert -- you may need to<br>// h=
ave some kind of wrapper type if it isn't legal to take<br>// a const&a=
mp;.<br>std::vector<matrix><br>add_scalar(std::initializer_<u></u>lis=
t<matrix const&> matrices,<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 std::initializer_list<int> scalars)<br=
>{<br>=A0 if(matrices.size() !=3D scalars.size()) {<br>=A0=A0=A0 assert(fal=
se && "Matrix scalar size mismatch!");<br>=A0=A0=A0 std::=
terminate(); // Don't throw for things that should terminate!<br>
=A0 }<br>=A0 <br>=A0 // Make exception safe copy:<br>=A0 std::vector<mat=
rix> result(begin(matricies), end(matricies));<br>=A0 auto si =3D begin(=
scalars); // Nothrow<br>=A0 for(matrix& m : result) // Norhrow<br>=A0 {=
<br>=A0=A0=A0=A0 m +=3D *si++; // Nothrow<br>
=A0 }<br>=A0 <br>=A0 return result;<br>}</div></div><div>=A0</div><div>Most=
importantly though, this is a niche case, not a common case. The original =
proposal was trying to support the common case of having a constructor with=
a sink argument. That is a compelling reason to add things to the standard=
-- I'm not sure this is, even in the couple of places where it may mak=
e sense..</div>
</div></div></div><div><div><div class=3D"h5"><br clear=3D"all"><div><div d=
ir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbucket.org=
/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</a></div><di=
v><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_b=
lank">http://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div></div><div class=3D"gmail_quote"><div><div class=3D"h5">On Su=
n, Sep 15, 2013 at 4:48 PM, Sumant Tambe <span dir=3D"ltr"><<a>sut...@gm=
ail.com</a>></span> wrote:<br></div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rg=
b(204,204,204);border-left-width:1px;border-left-style:solid">
<div><div class=3D"h5">
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4).=A0<br=
>
</div><div><br></div><div>1 to 2 % performance gain may or may not be "=
;worth" it. People should use their judgement. However, story does not=
end here.</div><div><br></div><div>Binary operator +() provides only one o=
pportunity for in<T> to save a copy. I.e., =A0when the right hand sid=
e object is an rvalue. The in<T> idiom shines the most when there are=
more opportunities to detect rvalues and to exploit them at run-time. So h=
ere is a small function to add scalars to a list of matrices.=A0</div>
<div><br></div><div><div>std::vector<matrix></div><div>add_scalar(std=
::initializer_<u></u>list<in<matrix>> matrices,</div><div>=A0 =
=A0 =A0 =A0 =A0 =A0std::initializer_list<int> scalars)</div><div>{</d=
iv><div>
=A0 if(matrices.size() !=3D scalars.size())</div>
<div>=A0 =A0 throw 0;</div><div><br></div><div>=A0 std::vector<matrix>=
; result;</div><div>=A0 result.reserve(matrices.size()<u></u>);</div><div>=
=A0=A0</div><div>=A0 auto si =3D begin(scalars);</div><div>=A0 for(const in=
<matrix> & m : matrices)</div>
<div>=A0 {</div><div>=A0 =A0 =A0if(m.rvalue()) {</div><div>=A0 =A0 =A0 =A0 =
cout << "rvalue matrix\n";</div><div>=A0 =A0 =A0 =A0 result=
..push_back(std::move(m.<u></u>rget() +=3D *si));</div><div>=A0 =A0 =A0}</di=
v><div>=A0 =A0 =A0else {</div><div>
=A0 =A0 =A0 =A0 cout << "lvalue matrix\n";</div>
<div>=A0 =A0 =A0 =A0 result.push_back(std::move(<u></u>matrix(m) +=3D *si))=
;</div><div>=A0 =A0 =A0}</div><div>=A0 }</div><div><br></div><div>=A0 retur=
n result;</div><div>}</div><div><br></div><div>And I call it like this:</di=
v><div><div><br>
</div>
<div>
matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { =
3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g++ 4.9 =
and clang 3.3.</div><div><br></div><div>In each use, this function gives fi=
nite but unknown number of opportunities to exploit move-semantics. I'm=
not sure if such a function can be easily implemented using universal refe=
rences. Variadic templates come to mind but two lists of parameters probabl=
y requires separate grouping. I guess it could be done using std::tuple and=
two variadic parameter packs of universal references. But std::make_tuple =
is not as pretty as std::initializer_list.</div>
<div><br></div><div>Surprisingly, in<T> works nicely with initializer=
_list<T>. Initilizer_list does not appear to retain rvalue/lvalue-nes=
s of the original parameter because initializer_list iterator is a pointer =
to consts. In<T>, however, allows the rvalue/lvalue knowledge of the =
original parameter pass through the initializer_list--here is the best part=
--without subverting const-correctness. All member functions in in<T>=
are const. =A0</div>
<div><br></div><div>Thoughts?</div><span><font color=3D"#888888"><div><br><=
/div><div>Sumant</div><br></font></span></div></div></div></div><div><div><=
div><div class=3D"h5">
<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></div></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<div class=
=3D"im"><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/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></div></blockquote></div><br></div>
</blockquote></div></div><div class=3D"HOEnZb"><div class=3D"h5">
<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>
</div></div></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 />
--047d7b5d452c71135504e685feaa--
.
Author: Sumant Tambe <sutambe@gmail.com>
Date: Mon, 16 Sep 2013 14:27:06 -0700 (PDT)
Raw View
------=_Part_777_1720651.1379366826145
Content-Type: text/plain; charset=ISO-8859-1
The point of the add_scalar example is, well, an example. Something to chew
on while I'm trying to get the value of in<T> across as I see it. Possible
overshadowing of move optimizations within that function are tangential to
the main discussion. And so it the exception safety of the implementation.
And so is the fact that I'm creating a vector each time.
in<T> gives a way to separate lvalues from rvalues at run-time and I'm
trying to solicit feedback on a pure library-based approach. Language
extensions tend to be substantially more complex, error-prone, harder to
convince (due to almost limitless freedom) and hard to test unless you know
a rockstar compiler dev. I'm trying hard to pickup useful nuggets here.
1. in<T> may interact with exception safety and may possibly
improve/degrade it. But that is not an inherent limitation of in<T>. It is
how it it used a certain piece of code.
2. if the benchmark is not doing what I think it is doing, any suggestions
to improve it? I think it shows noticeable (1-2%) difference. I not passing
any judgement on whether it is "worth" it. Statistically, sufficiently
large number of iterations should make the result reliable even though no
two runs are the same.
3. a library proposal and a language extension proposal for sink arguments
could live in parallel. Possibly learning and gaining momentum from each
other.
Thanks,
Sumant
On Monday, September 16, 2013 1:24:00 PM UTC-7, Billy O'Neal wrote:
>
> 1. Then I guess we just fundamentally disagree. Just because something is
> an rvalue at one point does not mean that it will stay that way if an
> exception is thrown. For instance, if the matrices come out of a vector
> with move() applied to the vector's elements. But if an exception is
> thrown, the caller probably doesn't want the vector to have been modified.
> 2. Ok, well that sucks for performance. Making the micro-optimization of
> being able to move in some cases is probably completely overshadowed by
> having to create new vectors every time for that particular call.
> 3. No, the moves are not necessary. Emplace them into the vector, and then
> apply += in their new positions. (As I demonstrated in my example)
> 4. That benchmark is flawed. On different runs you're executing completely
> different operations. Not to mention I would be hugely surprised if any
> compiler didn't just inline the whole thing and defeat the benchmark.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
> Malware Response Instructor - BleepingComputer.com
>
>
> On Mon, Sep 16, 2013 at 12:59 PM, Sumant Tambe <sut...@gmail.com<javascript:>
> > wrote:
>
>> @1 Striving for strong exception safety is a noble goal in general but in
>> the example I showed it seems unnecessary and imposes overhead. What
>> user-visible state are you trying to keep safe from exceptions? The
>> initiaizer_list does not live too long before and after the function it is
>> invoked for. The initializer_list could contain lvalues and those should be
>> protected from exceptions. I do that by making a copy only if there is an
>> lvalue. If an element is rvalue then by definition no one else has seen it
>> and therefore I move from it. Now any exception down the line will free the
>> result vector invoking destructors on the copies of lvalues and the moved
>> from rvalues. The lvalues that the iteration never reached to will remain
>> unchanged. Everything is still exception safe without the overhead of
>> copying all the initializer_list elements upfront and thereby loosing the
>> opportunities to move.
>> @2 That's right, I want to return a new vector every time.
>> @3 The moves are necessary in the code I've shown. operator += returns
>> matrix & and must be converted to matrix &&. emplace_back won't do any
>> magic in this case, IMO.
>>
>> Finally, on the main subject: I'm not sure since when
>> std::initializer_list has become a niche. Does the standard say that? It is
>> less common than writing a constructor, I agree but more likely than a
>> overleaded binary operator.
>>
>> And here is the benchmark routine. For the record, I don't benchmark with
>> I/O enabled.
>> void invoke_binary(int iter)
>> {
>> matrix s1, s2;
>> for(int i=0;i < iter; ++i)
>> {
>> int branch = rand() % 4;
>> switch(branch)
>> {
>> case 0: {
>> matrix m1 (matrix() + s1);
>> break;
>> }
>> case 1: {
>> matrix m2 (matrix() + matrix());
>> break;
>> }
>> case 2: {
>> matrix m3 (s1 + s2);
>> break;
>> }
>> case 3: {
>> matrix m4 (s1 + matrix());
>> break;
>> }
>> }
>> }
>> }
>>
>> On Monday, September 16, 2013 9:15:17 AM UTC-7, Billy O'Neal wrote:
>>
>>> Can you post the benchmark code? Not that I don't trust you, but 1-2% is
>>> well within the margin of error in most cases. In particular, any time you
>>> involve IO (e.g. std::cout) that's going to play havoc with benchmarks.
>>>
>>> Regarding your code example, that API is poor for 2 reasons:
>>> 1. doing in a way that is exception safe is impossible. The way to make
>>> it exception safe is just to make copies.
>>> 2. that interface forces creation of a new vector on every call.
>>> 3. you have way too many unnecessary moves in that example -- use
>>> emplace where possible. If T was something like std::array, move is not
>>> cheaper than copy.
>>>
>>> You can fix (1) using something like:
>>> // Note: I'm no initializer_list expert -- you may need to
>>> // have some kind of wrapper type if it isn't legal to take
>>> // a const&.
>>> std::vector<matrix>
>>> add_scalar(std::initializer_**list<matrix const&> matrices,
>>> std::initializer_list<int> scalars)
>>> {
>>> if(matrices.size() != scalars.size()) {
>>> assert(false && "Matrix scalar size mismatch!");
>>> std::terminate(); // Don't throw for things that should terminate!
>>> }
>>>
>>> // Make exception safe copy:
>>> std::vector<matrix> result(begin(matricies), end(matricies));
>>> auto si = begin(scalars); // Nothrow
>>> for(matrix& m : result) // Norhrow
>>> {
>>> m += *si++; // Nothrow
>>> }
>>>
>>> return result;
>>> }
>>>
>>> Most importantly though, this is a niche case, not a common case. The
>>> original proposal was trying to support the common case of having a
>>> constructor with a sink argument. That is a compelling reason to add things
>>> to the standard -- I'm not sure this is, even in the couple of places where
>>> it may make sense..
>>>
>>> Billy O'Neal
>>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>>> Malware Response Instructor - BleepingComputer.com
>>>
>>>
>>> On Sun, Sep 15, 2013 at 4:48 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>>
>>>> Thanks for the detailed analysis. I agree that in<T> is slightly
>>>> better in some cases and slightly inferior in others. I ran a benchmark and
>>>> saw about 1-2% improvement in performance when using in<T> as opposed to
>>>> the example #2 you proposed. Each run of the benchmark executed all 4
>>>> versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of
>>>> binary operator+ with equal probability (rand() % 4).
>>>>
>>>> 1 to 2 % performance gain may or may not be "worth" it. People should
>>>> use their judgement. However, story does not end here.
>>>>
>>>> Binary operator +() provides only one opportunity for in<T> to save a
>>>> copy. I.e., when the right hand side object is an rvalue. The in<T> idiom
>>>> shines the most when there are more opportunities to detect rvalues and to
>>>> exploit them at run-time. So here is a small function to add scalars to a
>>>> list of matrices.
>>>>
>>>> std::vector<matrix>
>>>> add_scalar(std::initializer_**list<in<matrix>> matrices,
>>>> std::initializer_list<int> scalars)
>>>> {
>>>> if(matrices.size() != scalars.size())
>>>> throw 0;
>>>>
>>>> std::vector<matrix> result;
>>>> result.reserve(matrices.size()**);
>>>>
>>>> auto si = begin(scalars);
>>>> for(const in<matrix> & m : matrices)
>>>> {
>>>> if(m.rvalue()) {
>>>> cout << "rvalue matrix\n";
>>>> result.push_back(std::move(m.**rget() += *si));
>>>> }
>>>> else {
>>>> cout << "lvalue matrix\n";
>>>> result.push_back(std::move(**matrix(m) += *si));
>>>> }
>>>> }
>>>>
>>>> return result;
>>>> }
>>>>
>>>> And I call it like this:
>>>>
>>>> matrix s1, s2, s3, s4;
>>>> add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
>>>>
>>>> I tested this code on g++ 4.9 and clang 3.3.
>>>>
>>>> In each use, this function gives finite but unknown number of
>>>> opportunities to exploit move-semantics. I'm not sure if such a function
>>>> can be easily implemented using universal references. Variadic templates
>>>> come to mind but two lists of parameters probably requires separate
>>>> grouping. I guess it could be done using std::tuple and two variadic
>>>> parameter packs of universal references. But std::make_tuple is not as
>>>> pretty as std::initializer_list.
>>>>
>>>> Surprisingly, in<T> works nicely with initializer_list<T>.
>>>> Initilizer_list does not appear to retain rvalue/lvalue-ness of the
>>>> original parameter because initializer_list iterator is a pointer to
>>>> consts. In<T>, however, allows the rvalue/lvalue knowledge of the original
>>>> parameter pass through the initializer_list--here is the best part--without
>>>> subverting const-correctness. All member functions in in<T> are const.
>>>>
>>>> Thoughts?
>>>>
>>>> Sumant
>>>>
>>>> --
>>>>
>>>> ---
>>>> 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-proposal...@**isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>>
>>>> Visit this group at http://groups.google.com/a/**isocpp.org/group/std-*
>>>> *proposals/<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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> 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/.
------=_Part_777_1720651.1379366826145
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The point of the add_scalar example is, well, an example. =
Something to chew on while I'm trying to get the value of in<T> acros=
s as I see it. Possible overshadowing of move optimizations within that fun=
ction are tangential to the main discussion. And so it the exception safety=
of the implementation. And so is the fact that I'm creating a vector each =
time.<div><br></div><div>in<T> gives a way to separate lvalues from r=
values at run-time and I'm trying to solicit feedback on a pure library-bas=
ed approach. Language extensions tend to be substantially more complex, err=
or-prone, harder to convince (due to almost limitless freedom) and hard to =
test unless you know a rockstar compiler dev. I'm trying hard to pickup use=
ful nuggets here.</div><div><br></div><div>1. in<T> may interact with=
exception safety and may possibly improve/degrade it. But that is not an i=
nherent limitation of in<T>. It is how it it used a certain piece of =
code.</div><div>2. if the benchmark is not doing what I think it is doing, =
any suggestions to improve it? I think it shows noticeable (1-2%) differenc=
e. I not passing any judgement on whether it is "worth" it. Statistically, =
sufficiently large number of iterations should make the result reliable eve=
n though no two runs are the same.</div><div>3. a library proposal and a la=
nguage extension proposal for sink arguments could live in parallel. Possib=
ly learning and gaining momentum from each other.<br></div><div><br></div><=
div>Thanks,</div><div>Sumant</div><div><br></div><div>On Monday, September =
16, 2013 1:24:00 PM UTC-7, Billy O'Neal wrote:<blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div>1. Then I guess we just fundamentally=
disagree. Just because something is an rvalue at one point does not mean t=
hat it will stay that way if an exception is thrown. For instance, if the m=
atrices come out of a vector with move() applied to the vector's elements. =
But if an exception is thrown, the caller probably doesn't want the vector =
to have been modified.</div>
<div>2. Ok, well that sucks for performance. Making the micro-optimization =
of being able to move in some cases is probably completely overshadowed by =
having to create new vectors every time for that particular call.</div>
<div>3. No, the moves are not necessary. Emplace them into the vector, and =
then apply +=3D in their new positions. (As I demonstrated in my example)</=
div><div>4. That benchmark is flawed. On different runs you're executi=
ng completely different operations. Not to mention I would be hugely surpri=
sed if any compiler didn't just inline the whole thing and defeat the bench=
mark.</div>
</div><div><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/u=
sers/82320/billy-oneal" target=3D"_blank">http://stackoverflow.com/<wbr>use=
rs/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Mon, Sep 16, 2013 at 12:59 PM, Sumant=
Tambe <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-=
obfuscated-mailto=3D"2-VOWH_vhicJ">sut...@gmail.com</a>></span> wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">@1 Striving for strong exception safety is a noble goal in=
general but in the example I showed it seems unnecessary and imposes overh=
ead. What user-visible state are you trying to keep safe from exceptions? T=
he initiaizer_list does not live too long before and after the function it =
is invoked for. The initializer_list could contain lvalues and those should=
be protected from exceptions. I do that by making a copy only if there is =
an lvalue. If an element is rvalue then by definition no one else has seen =
it and therefore I move from it. Now any exception down the line will free =
the result vector invoking destructors on the copies of lvalues and the mov=
ed from rvalues. The lvalues that the iteration never reached to will remai=
n unchanged. Everything is still exception safe without the overhead of cop=
ying all the initializer_list elements upfront and thereby loosing the oppo=
rtunities to move.<div>
@2 That's right, I want to return a new vector every time.<br></div><div>@3=
The moves are necessary in the code I've shown. operator +=3D returns matr=
ix & and must be converted to matrix &&. emplace_back won't do =
any magic in this case, IMO.<br>
</div><div><br></div><div>Finally, on the main subject: I'm not sure since =
when std::initializer_list has become a niche. Does the standard say that? =
It is less common than writing a constructor, I agree but more likely than =
a overleaded binary operator.</div>
<div><br></div><div>And here is the benchmark routine. For the record, I do=
n't benchmark with I/O enabled.</div><div><div>void invoke_binary(int iter)=
</div><div>{</div><div> matrix s1, s2;</div><div> for(int i=3D0=
;i < iter; ++i)</div>
<div> {</div><div> int branch =3D rand() % 4;</div><div>=
switch(branch)</div><div> {</div><div> &nb=
sp; case 0: {</div><div><div> matrix m1 (=
matrix() + s1);</div></div><div> break;</div><di=
v>
}</div><div> case 1: {</div><div><=
div> matrix m2 (matrix() + matrix());</div></div=
><div> break;</div><div> }</=
div><div> case 2: {</div><div><div> =
matrix m3 (s1 + s2);</div>
</div><div> break;</div><div>  =
; }</div><div> case 3: {</div><div><div> &=
nbsp; matrix m4 (s1 + matrix());</div></div><div>  =
; break;</div><div> }</div><div> } =
</div><div> }</div><div>
}</div></div><div><div><div><br>On Monday, September 16, 2013 9:15:17 AM UT=
C-7, Billy O'Neal wrote:</div></div><blockquote class=3D"gmail_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">
<div><div><div dir=3D"ltr"><div>Can you post the benchmark code? Not that I=
don't trust you, but 1-2% is well within the margin of error in most cases=
.. In particular, any time you involve IO (e.g. std::cout) that's going to p=
lay havoc with benchmarks.</div>
<div> </div><div>Regarding your code example, that API is poor for 2 r=
easons:</div><div>1. doing in a way that is exception safe is impossible. T=
he way to make it exception safe is just to make copies.</div><div>2. that =
interface forces creation of a new vector on every call.</div>
<div>3. you have way too many unnecessary moves in that example -- use empl=
ace where possible. If T was something like std::array, move is not cheaper=
than copy.</div><div><div> </div><div>You can fix (1) using something=
like:</div>
<div>// Note: I'm no initializer_list expert -- you may need to<br>// have =
some kind of wrapper type if it isn't legal to take<br>// a const&.<br>=
std::vector<matrix><br>add_scalar(std::initializer_<u></u>li<wbr>st&l=
t;matrix const&> matrices,<br>
std::initializ=
er_list<int> scalars)<br>{<br> if(matrices.size() !=3D scalars.=
size()) {<br> assert(false && "Matrix scalar size=
mismatch!");<br> std::terminate(); // Don't throw for th=
ings that should terminate!<br>
}<br> <br> // Make exception safe copy:<br> std::v=
ector<matrix> result(begin(matricies), end(matricies));<br> aut=
o si =3D begin(scalars); // Nothrow<br> for(matrix& m : result) /=
/ Norhrow<br> {<br> m +=3D *si++; // Nothrow<=
br>
}<br> <br> return result;<br>}</div></div><div> </d=
iv><div>Most importantly though, this is a niche case, not a common case. T=
he original proposal was trying to support the common case of having a cons=
tructor with a sink argument. That is a compelling reason to add things to =
the standard -- I'm not sure this is, even in the couple of places where it=
may make sense..</div>
</div></div></div><div><div><div><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" tar=
get=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"http=
://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://stac=
koverflow.com/<u></u>users<wbr>/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div></div><div class=3D"gmail_quote"><div><div>On Sun, Sep 15, 20=
13 at 4:48 PM, Sumant Tambe <span dir=3D"ltr"><<a>sut...@gmail.com</a>&g=
t;</span> wrote:<br></div></div><blockquote class=3D"gmail_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">
<div><div>
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4). =
<br>
</div><div><br></div><div>1 to 2 % performance gain may or may not be "wort=
h" it. People should use their judgement. However, story does not end here.=
</div><div><br></div><div>Binary operator +() provides only one opportunity=
for in<T> to save a copy. I.e., when the right hand side objec=
t is an rvalue. The in<T> idiom shines the most when there are more o=
pportunities to detect rvalues and to exploit them at run-time. So here is =
a small function to add scalars to a list of matrices. </div>
<div><br></div><div><div>std::vector<matrix></div><div>add_scalar(std=
::initializer_<u></u>li<wbr>st<in<matrix>> matrices,</div><div>=
std::initializer_list<int> s=
calars)</div><div>{</div><div>
if(matrices.size() !=3D scalars.size())</div>
<div> throw 0;</div><div><br></div><div> std::vector<=
matrix> result;</div><div> result.reserve(matrices.size()<u></u><w=
br>);</div><div> </div><div> auto si =3D begin(scalars);</=
div><div> for(const in<matrix> & m : matrices)</div>
<div> {</div><div> if(m.rvalue()) {</div><div>&nbs=
p; cout << "rvalue matrix\n";</div><div> &=
nbsp; result.push_back(std::move(m.<u></u>r<wbr>get() +=3D *s=
i));</div><div> }</div><div> else {</=
div><div>
cout << "lvalue matrix\n";</div>
<div> result.push_back(std::move(<u></u>mat<wbr>=
rix(m) +=3D *si));</div><div> }</div><div> }</div>=
<div><br></div><div> return result;</div><div>}</div><div><br></div><=
div>And I call it like this:</div><div><div><br>
</div>
<div>
matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { =
3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g++ 4.9 =
and clang 3.3.</div><div><br></div><div>In each use, this function gives fi=
nite but unknown number of opportunities to exploit move-semantics. I'm not=
sure if such a function can be easily implemented using universal referenc=
es. Variadic templates come to mind but two lists of parameters probably re=
quires separate grouping. I guess it could be done using std::tuple and two=
variadic parameter packs of universal references. But std::make_tuple is n=
ot as pretty as std::initializer_list.</div>
<div><br></div><div>Surprisingly, in<T> works nicely with initializer=
_list<T>. Initilizer_list does not appear to retain rvalue/lvalue-nes=
s of the original parameter because initializer_list iterator is a pointer =
to consts. In<T>, however, allows the rvalue/lvalue knowledge of the =
original parameter pass through the initializer_list--here is the best part=
--without subverting const-correctness. All member functions in in<T>=
are const. </div>
<div><br></div><div>Thoughts?</div><span><font color=3D"#888888"><div><br><=
/div><div>Sumant</div><br></font></span></div></div></div></div><div><div><=
div><div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br></div></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<div><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/<u></u>iso<wbr=
>cpp.org/group/std-<u></u>proposals/</a>.<br>
</div></div></div></blockquote></div><br></div>
</blockquote></div></div><div><div>
<p></p>
-- <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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
2-VOWH_vhicJ">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"2-VOWH_vhicJ">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</blockquote></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_777_1720651.1379366826145--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Mon, 16 Sep 2013 16:29:28 -0700
Raw View
--001a11c2047abf0ad104e68895ed
Content-Type: text/plain; charset=ISO-8859-1
>Not if Richard's NB comment 12 (http://www.open-std.org/jtc1/
sc22/wg21/docs/papers/2013/n3733.pdf, search for "US 12") is properly
resolved - which allows copy / move elision from xvalues.
Fair enough. :) But at the moment it isn't resolved (and isn't resolved for
C++11), so I'm going to keep giving that advice until it changes.
>The point of the add_scalar example is, well, an example. Something to
chew on while I'm trying to get the value of in<T> across as I see it.
Possible overshadowing of move optimizations within that function are
tangential to the main discussion.
No, they aren't tangential to that discussion at all. If you want the
proposal to be taken seriously, you need to show a serious case where it
makes a positive difference to clarity and/or performance or has some other
benefit. At the moment, you haven't shown an example that I'd consider
"motivating". And by that I mean an example where an idiot like myself
can't poke bunches of holes in 10 minutes or less. If a user can't consider
using the type in<T> or sink<T> in a high quality library, then it probably
isn't appropriate in the standard. But I'm not on the committee, so what do
I know?
>in<T> gives a way to separate lvalues from rvalues at run-time and I'm
trying to solicit feedback on a pure library-based approach.
Yes, and I am giving you my feedback. That unless you can show a real world
use case where it actually is an improvement, I think it is a bad idea as
presented; adding complexity for little to no gain in perf.
>1. in<T> may interact with exception safety and may possibly
improve/degrade it. But that is not an inherent limitation of in<T>. It is
how it it used a certain piece of code.
(see above). You have to show a good use to motivate its inclusion in the
standard. Your original use case (passing things into a constructor) was a
great use case, but again I don't think it is implementable. (If it is
implementable, that would be awesome)
>2. if the benchmark is not doing what I think it is doing, any suggestions
to improve it? I think it shows noticeable (1-2%) difference. I not passing
any judgement on whether it is "worth" it. Statistically, sufficiently
large number of iterations should make the result reliable even though no
two runs are the same.
Make sure your compiler isn't inlining the whole thing and defeating the
benchmark. You can put each candidate in a separate function and ask your
compiler never to inline that function (most compilers will allow this)
Don't use rand() in a benchmark -- make it a deterministic set of work that
others can replicate to show your approach is superior.
Consider making the difference between a copy and a move for matrix larger
to show a larger than 1-2% difference; e.g. pass around matrices with more
elements.
Include the mechanism you use to measure time in your benchmark, and use
the highest resolution clock available on your platform. (e.g. C++11
high_resolution_clock; QueryPerformanceCounter on Windows).
Run the benchmark multiple times in the same program, and discard the first
couple of runs of each candidate solution to eliminate effects of initial
code loading and similar.
Writing good benchmarks is really Really REALLY hard, particularly for
micro-optimization cases like this.
===================================
How about an example like this?
class Foo
{
optional<string> member; // Optional allows the data to be
uninitialized.
public:
Foo(in<string> str)
{
if (str.is_rvalue())
{
member.emplace(str.rget()); // move construct string
}
else
{
member.emplace(str.lget()); // copy construct string
}
}
void MemberFunction()
{
// use member
std::cout << *member;
}
};
Unfortunately for more than one argument this is still not exception safe
:(. On the other hand, when you have more than one parameter, the potential
for collision with the special member functions goes away, so the argument
against using perfect forwarding instead is much less strongly in favor of
in<T>.
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Mon, Sep 16, 2013 at 2:27 PM, Sumant Tambe <sutambe@gmail.com> wrote:
> The point of the add_scalar example is, well, an example. Something to
> chew on while I'm trying to get the value of in<T> across as I see it.
> Possible overshadowing of move optimizations within that function are
> tangential to the main discussion. And so it the exception safety of the
> implementation. And so is the fact that I'm creating a vector each time.
>
> in<T> gives a way to separate lvalues from rvalues at run-time and I'm
> trying to solicit feedback on a pure library-based approach. Language
> extensions tend to be substantially more complex, error-prone, harder to
> convince (due to almost limitless freedom) and hard to test unless you know
> a rockstar compiler dev. I'm trying hard to pickup useful nuggets here.
>
> 1. in<T> may interact with exception safety and may possibly
> improve/degrade it. But that is not an inherent limitation of in<T>. It is
> how it it used a certain piece of code.
> 2. if the benchmark is not doing what I think it is doing, any suggestions
> to improve it? I think it shows noticeable (1-2%) difference. I not passing
> any judgement on whether it is "worth" it. Statistically, sufficiently
> large number of iterations should make the result reliable even though no
> two runs are the same.
> 3. a library proposal and a language extension proposal for sink arguments
> could live in parallel. Possibly learning and gaining momentum from each
> other.
>
> Thanks,
> Sumant
>
> On Monday, September 16, 2013 1:24:00 PM UTC-7, Billy O'Neal wrote:
>
>> 1. Then I guess we just fundamentally disagree. Just because something is
>> an rvalue at one point does not mean that it will stay that way if an
>> exception is thrown. For instance, if the matrices come out of a vector
>> with move() applied to the vector's elements. But if an exception is
>> thrown, the caller probably doesn't want the vector to have been modified.
>> 2. Ok, well that sucks for performance. Making the micro-optimization of
>> being able to move in some cases is probably completely overshadowed by
>> having to create new vectors every time for that particular call.
>> 3. No, the moves are not necessary. Emplace them into the vector, and
>> then apply += in their new positions. (As I demonstrated in my example)
>> 4. That benchmark is flawed. On different runs you're executing
>> completely different operations. Not to mention I would be hugely surprised
>> if any compiler didn't just inline the whole thing and defeat the benchmark.
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/**users/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>> Malware Response Instructor - BleepingComputer.com
>>
>>
>> On Mon, Sep 16, 2013 at 12:59 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>
>>> @1 Striving for strong exception safety is a noble goal in general but
>>> in the example I showed it seems unnecessary and imposes overhead. What
>>> user-visible state are you trying to keep safe from exceptions? The
>>> initiaizer_list does not live too long before and after the function it is
>>> invoked for. The initializer_list could contain lvalues and those should be
>>> protected from exceptions. I do that by making a copy only if there is an
>>> lvalue. If an element is rvalue then by definition no one else has seen it
>>> and therefore I move from it. Now any exception down the line will free the
>>> result vector invoking destructors on the copies of lvalues and the moved
>>> from rvalues. The lvalues that the iteration never reached to will remain
>>> unchanged. Everything is still exception safe without the overhead of
>>> copying all the initializer_list elements upfront and thereby loosing the
>>> opportunities to move.
>>> @2 That's right, I want to return a new vector every time.
>>> @3 The moves are necessary in the code I've shown. operator += returns
>>> matrix & and must be converted to matrix &&. emplace_back won't do any
>>> magic in this case, IMO.
>>>
>>> Finally, on the main subject: I'm not sure since when
>>> std::initializer_list has become a niche. Does the standard say that? It is
>>> less common than writing a constructor, I agree but more likely than a
>>> overleaded binary operator.
>>>
>>> And here is the benchmark routine. For the record, I don't benchmark
>>> with I/O enabled.
>>> void invoke_binary(int iter)
>>> {
>>> matrix s1, s2;
>>> for(int i=0;i < iter; ++i)
>>> {
>>> int branch = rand() % 4;
>>> switch(branch)
>>> {
>>> case 0: {
>>> matrix m1 (matrix() + s1);
>>> break;
>>> }
>>> case 1: {
>>> matrix m2 (matrix() + matrix());
>>> break;
>>> }
>>> case 2: {
>>> matrix m3 (s1 + s2);
>>> break;
>>> }
>>> case 3: {
>>> matrix m4 (s1 + matrix());
>>> break;
>>> }
>>> }
>>> }
>>> }
>>>
>>> On Monday, September 16, 2013 9:15:17 AM UTC-7, Billy O'Neal wrote:
>>>
>>>> Can you post the benchmark code? Not that I don't trust you, but 1-2%
>>>> is well within the margin of error in most cases. In particular, any time
>>>> you involve IO (e.g. std::cout) that's going to play havoc with benchmarks.
>>>>
>>>> Regarding your code example, that API is poor for 2 reasons:
>>>> 1. doing in a way that is exception safe is impossible. The way to make
>>>> it exception safe is just to make copies.
>>>> 2. that interface forces creation of a new vector on every call.
>>>> 3. you have way too many unnecessary moves in that example -- use
>>>> emplace where possible. If T was something like std::array, move is not
>>>> cheaper than copy.
>>>>
>>>> You can fix (1) using something like:
>>>> // Note: I'm no initializer_list expert -- you may need to
>>>> // have some kind of wrapper type if it isn't legal to take
>>>> // a const&.
>>>> std::vector<matrix>
>>>> add_scalar(std::initializer_**li**st<matrix const&> matrices,
>>>> std::initializer_list<int> scalars)
>>>> {
>>>> if(matrices.size() != scalars.size()) {
>>>> assert(false && "Matrix scalar size mismatch!");
>>>> std::terminate(); // Don't throw for things that should terminate!
>>>> }
>>>>
>>>> // Make exception safe copy:
>>>> std::vector<matrix> result(begin(matricies), end(matricies));
>>>> auto si = begin(scalars); // Nothrow
>>>> for(matrix& m : result) // Norhrow
>>>> {
>>>> m += *si++; // Nothrow
>>>> }
>>>>
>>>> return result;
>>>> }
>>>>
>>>> Most importantly though, this is a niche case, not a common case. The
>>>> original proposal was trying to support the common case of having a
>>>> constructor with a sink argument. That is a compelling reason to add things
>>>> to the standard -- I'm not sure this is, even in the couple of places where
>>>> it may make sense..
>>>>
>>>> Billy O'Neal
>>>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>>>> http://stackoverflow.com/**users**/82320/billy-oneal<http://stackoverflow.com/users/82320/billy-oneal>
>>>> Malware Response Instructor - BleepingComputer.com
>>>>
>>>>
>>>> On Sun, Sep 15, 2013 at 4:48 PM, Sumant Tambe <sut...@gmail.com> wrote:
>>>>
>>>>> Thanks for the detailed analysis. I agree that in<T> is slightly
>>>>> better in some cases and slightly inferior in others. I ran a benchmark and
>>>>> saw about 1-2% improvement in performance when using in<T> as opposed to
>>>>> the example #2 you proposed. Each run of the benchmark executed all 4
>>>>> versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rvalue-rvalue) of
>>>>> binary operator+ with equal probability (rand() % 4).
>>>>>
>>>>> 1 to 2 % performance gain may or may not be "worth" it. People should
>>>>> use their judgement. However, story does not end here.
>>>>>
>>>>> Binary operator +() provides only one opportunity for in<T> to save a
>>>>> copy. I.e., when the right hand side object is an rvalue. The in<T> idiom
>>>>> shines the most when there are more opportunities to detect rvalues and to
>>>>> exploit them at run-time. So here is a small function to add scalars to a
>>>>> list of matrices.
>>>>>
>>>>> std::vector<matrix>
>>>>> add_scalar(std::initializer_**li**st<in<matrix>> matrices,
>>>>> std::initializer_list<int> scalars)
>>>>> {
>>>>> if(matrices.size() != scalars.size())
>>>>> throw 0;
>>>>>
>>>>> std::vector<matrix> result;
>>>>> result.reserve(matrices.size()****);
>>>>>
>>>>> auto si = begin(scalars);
>>>>> for(const in<matrix> & m : matrices)
>>>>> {
>>>>> if(m.rvalue()) {
>>>>> cout << "rvalue matrix\n";
>>>>> result.push_back(std::move(m.**r**get() += *si));
>>>>> }
>>>>> else {
>>>>> cout << "lvalue matrix\n";
>>>>> result.push_back(std::move(**mat**rix(m) += *si));
>>>>> }
>>>>> }
>>>>>
>>>>> return result;
>>>>> }
>>>>>
>>>>> And I call it like this:
>>>>>
>>>>> matrix s1, s2, s3, s4;
>>>>> add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { 3, 5, 7, 9});
>>>>>
>>>>> I tested this code on g++ 4.9 and clang 3.3.
>>>>>
>>>>> In each use, this function gives finite but unknown number of
>>>>> opportunities to exploit move-semantics. I'm not sure if such a function
>>>>> can be easily implemented using universal references. Variadic templates
>>>>> come to mind but two lists of parameters probably requires separate
>>>>> grouping. I guess it could be done using std::tuple and two variadic
>>>>> parameter packs of universal references. But std::make_tuple is not as
>>>>> pretty as std::initializer_list.
>>>>>
>>>>> Surprisingly, in<T> works nicely with initializer_list<T>.
>>>>> Initilizer_list does not appear to retain rvalue/lvalue-ness of the
>>>>> original parameter because initializer_list iterator is a pointer to
>>>>> consts. In<T>, however, allows the rvalue/lvalue knowledge of the original
>>>>> parameter pass through the initializer_list--here is the best part--without
>>>>> subverting const-correctness. All member functions in in<T> are const.
>>>>>
>>>>> Thoughts?
>>>>>
>>>>> Sumant
>>>>>
>>>>> --
>>>>>
>>>>> ---
>>>>> 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-proposal...@**isocpp.org.
>>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>>>
>>>>> Visit this group at http://groups.google.com/a/**iso**
>>>>> cpp.org/group/std-**proposals/<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-proposal...@**isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at http://groups.google.com/a/**isocpp.org/group/std-**
>>> proposals/ <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/.
>
--
---
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/.
--001a11c2047abf0ad104e68895ed
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>>Not if Richard's NB comment 12 (<a href=3D"ht=
tp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3733.pdf" target=3D"=
_blank"><font color=3D"#0066cc">http://www.open-std.org/jtc1/</font><font c=
olor=3D"#0066cc">sc22/wg21/docs/papers/2013/</font><font color=3D"#0066cc">=
n3733.pdf</font></a>, search for "US 12") is properly resolved - =
which allows copy / move elision from xvalues.</div>
<div>=A0</div><div>Fair enough. :) But at the moment it isn't resolved =
(and isn't resolved for C++11), so I'm going to keep giving that ad=
vice until it changes.</div><div>=A0</div><div>>The point of the add_sca=
lar example is, well, an example. Something to chew on while I'm trying=
to get the value of in<T> across as I see it. Possible overshadowing=
of move optimizations within that function are tangential to the main disc=
ussion.</div>
<div>=A0</div><div>No, they aren't tangential to that discussion at all=
.. If you want the proposal to be taken seriously, you need to show a seriou=
s case where it makes a positive difference to clarity and/or performance o=
r has some other benefit. At the moment, you haven't shown an example t=
hat I'd consider "motivating".=A0And by that I mean an exampl=
e where an=A0idiot like myself can't poke bunches of holes in 10 minute=
s or less.=A0If=A0a user=A0can't consider using the type=A0in<T> =
or sink<T>=A0in a high quality library, then it probably isn't ap=
propriate in the standard. But I'm not on the committee, so what do I k=
now?</div>
<div>=A0</div><div>>in<T> gives a way to separate lvalues from rva=
lues at run-time and I'm trying to solicit feedback on a pure library-b=
ased approach.</div><div>=A0</div><div>Yes, and I am giving you my feedback=
.. That unless you can show a real world use case where it actually is an im=
provement, I think it is a bad idea as presented; adding complexity for lit=
tle to no gain in perf.</div>
<div>=A0</div><div>>1. in<T> may interact with exception safety an=
d may possibly improve/degrade it. But that is not an inherent limitation o=
f in<T>. It is how it it used a certain piece of code.</div><div>=A0<=
/div>
<div>(see above). You have to show a good use to motivate its inclusion in =
the standard. Your original use case (passing things into a constructor) wa=
s a great use case, but again I don't think it is implementable. (If it=
is implementable, that would be awesome)</div>
<div>=A0</div><div>>2. if the benchmark is not doing what I think it is =
doing, any suggestions to improve it? I think it shows noticeable (1-2%) di=
fference. I not passing any judgement on whether it is "worth" it=
.. Statistically, sufficiently large number of iterations should make the re=
sult reliable even though no two runs are the same.</div>
<div>=A0</div><div>Make sure your compiler isn't inlining the whole thi=
ng and defeating the benchmark. You can put each candidate in a separate fu=
nction and ask your compiler never to inline that function (most compilers =
will allow this)</div>
<div>Don't use rand() in a benchmark -- make it a deterministic set of =
work that others can replicate to show your approach is superior.</div><div=
>Consider making the difference between a copy and a move for matrix larger=
to show a larger than 1-2% difference; e.g. pass around matrices with more=
elements.</div>
<div>Include the mechanism you use to measure time in your benchmark, and u=
se the highest resolution clock available on your platform. (e.g. C++11 hig=
h_resolution_clock; QueryPerformanceCounter on Windows).</div><div>Run the =
benchmark multiple times in the same program, and discard the first couple =
of runs of each candidate solution to eliminate effects of initial code loa=
ding and similar.</div>
<div>=A0</div><div>Writing good benchmarks is really Really REALLY=A0hard, =
particularly for micro-optimization cases like this.</div><div>=A0</div><di=
v>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D</div><div>=A0</div><div>How about an exam=
ple like this?</div>
<div>=A0</div><div><font face=3D"courier new,monospace">class Foo</font></d=
iv><div><font face=3D"courier new,monospace">{</font></div><div><font face=
=3D"courier new,monospace">=A0=A0=A0 optional<string> member; // Opti=
onal allows the data to be uninitialized.</font></div>
<div><font face=3D"courier new,monospace">public:</font></div><div><font fa=
ce=3D"courier new,monospace">=A0=A0=A0 Foo(in<string> str)</font></di=
v><div><font face=3D"courier new,monospace">=A0=A0=A0 {</font></div><div><f=
ont face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 if (str.is_rvalue(=
))</font></div>
<div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 {</font></d=
iv><div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 member.emplace(str.rget()); // move construct string</font></div><div><=
font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 }</font></div>
<div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0else</fon=
t></div><div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 {</=
font></div><div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 member.emplace(str.lget()); // copy construct string</font></d=
iv>
<div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 }</font></d=
iv><div><font face=3D"courier new,monospace">=A0=A0=A0 }</font></div><div><=
font face=3D"courier new,monospace"></font>=A0</div><div><font face=3D"cour=
ier new,monospace">=A0=A0=A0 void MemberFunction()</font></div>
<div><font face=3D"courier new,monospace">=A0=A0=A0 {</font></div><div><fon=
t face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0 // use member</font>=
</div><div><font face=3D"courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0std=
::cout << *member;</font></div>
<div>
<font face=3D"courier new,monospace">=A0=A0=A0 }</font></div><div><font fac=
e=3D"courier new,monospace">};</font></div><div>=A0</div><div>Unfortunately=
for more than one argument this is still not exception safe :(. On the oth=
er hand, when you have more than one parameter, the potential for collision=
with the special member functions goes away, so the argument against using=
perfect forwarding instead is much less strongly in favor of in<T>.<=
/div>
<div>=A0</div><div class=3D"gmail_extra"><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://sta=
ckoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://stackoverf=
low.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Mon, Sep 16, 2013 at 2:27 PM, Sumant =
Tambe <span dir=3D"ltr"><<a href=3D"mailto:sutambe@gmail.com" target=3D"=
_blank">sutambe@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-co=
lor:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
<div dir=3D"ltr">The point of the add_scalar example is, well, an example. =
Something to chew on while I'm trying to get the value of in<T> a=
cross as I see it. Possible overshadowing of move optimizations within that=
function are tangential to the main discussion. And so it the exception sa=
fety of the implementation. And so is the fact that I'm creating a vect=
or each time.<div>
<br></div><div>in<T> gives a way to separate lvalues from rvalues at =
run-time and I'm trying to solicit feedback on a pure library-based app=
roach. Language extensions tend to be substantially more complex, error-pro=
ne, harder to convince (due to almost limitless freedom) and hard to test u=
nless you know a rockstar compiler dev. I'm trying hard to pickup usefu=
l nuggets here.</div>
<div><br></div><div>1. in<T> may interact with exception safety and m=
ay possibly improve/degrade it. But that is not an inherent limitation of i=
n<T>. It is how it it used a certain piece of code.</div><div>2. if t=
he benchmark is not doing what I think it is doing, any suggestions to impr=
ove it? I think it shows noticeable (1-2%) difference. I not passing any ju=
dgement on whether it is "worth" it. Statistically, sufficiently =
large number of iterations should make the result reliable even though no t=
wo runs are the same.</div>
<div>3. a library proposal and a language extension proposal for sink argum=
ents could live in parallel. Possibly learning and gaining momentum from ea=
ch other.<br></div><div><br></div><div>Thanks,</div><div>Sumant</div><div>
<br></div><div><div class=3D"im">On Monday, September 16, 2013 1:24:00 PM U=
TC-7, Billy O'Neal wrote:</div><blockquote class=3D"gmail_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">
<div class=3D"im"><div dir=3D"ltr"><div>1. Then I guess we just fundamental=
ly disagree. Just because something is an rvalue at one point does not mean=
that it will stay that way if an exception is thrown. For instance, if the=
matrices come out of a vector with move() applied to the vector's elem=
ents. But if an exception is thrown, the caller probably doesn't want t=
he vector to have been modified.</div>
<div>2. Ok, well that sucks for performance. Making the micro-optimization =
of being able to move in some cases is probably completely overshadowed by =
having to create new vectors every time for that particular call.</div>
<div>3. No, the moves are not necessary. Emplace them into the vector, and =
then apply +=3D in their new positions. (As I demonstrated in my example)</=
div><div>4.=A0That benchmark is flawed. On different runs you're execut=
ing completely different operations. Not to mention I would be hugely surpr=
ised if any compiler didn't just inline the whole thing and defeat the =
benchmark.</div>
</div></div><div><div class=3D"im"><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">htt=
p://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div><div><div class=3D"h5"><div class=3D"gmail_quote">On Mon, Sep=
16, 2013 at 12:59 PM, Sumant Tambe <span dir=3D"ltr"><<a>sut...@gmail.c=
om</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);bo=
rder-left-width:1px;border-left-style:solid">
<div dir=3D"ltr">@1 Striving for strong exception safety is a noble goal in=
general but in the example I showed it seems unnecessary and imposes overh=
ead. What user-visible state are you trying to keep safe from exceptions? T=
he initiaizer_list does not live too long before and after the function it =
is invoked for. The initializer_list could contain lvalues and those should=
be protected from exceptions. I do that by making a copy only if there is =
an lvalue. If an element is rvalue then by definition no one else has seen =
it and therefore I move from it. Now any exception down the line will free =
the result vector invoking destructors on the copies of lvalues and the mov=
ed from rvalues. The lvalues that the iteration never reached to will remai=
n unchanged. Everything is still exception safe without the overhead of cop=
ying all the initializer_list elements upfront and thereby loosing the oppo=
rtunities to move.<div>
@2 That's right, I want to return a new vector every time.<br></div><di=
v>@3 The moves are necessary in the code I've shown. operator +=3D retu=
rns matrix & and must be converted to matrix &&. emplace_back w=
on't do any magic in this case, IMO.<br>
</div><div><br></div><div>Finally, on the main subject: I'm not sure si=
nce when std::initializer_list has become a niche. Does the standard say th=
at? It is less common than writing a constructor, I agree but more likely t=
han a overleaded binary operator.</div>
<div><br></div><div>And here is the benchmark routine. For the record, I do=
n't benchmark with I/O enabled.</div><div><div>void invoke_binary(int i=
ter)</div><div>{</div><div>=A0 matrix s1, s2;</div><div>=A0 for(int i=3D0;i=
< iter; ++i)</div>
<div>=A0 {</div><div>=A0 =A0 int branch =3D rand() % 4;</div><div>=A0 =A0 s=
witch(branch)</div><div>=A0 =A0 {</div><div>=A0 =A0 =A0 case 0: {</div><div=
><div>=A0 =A0 =A0 =A0 matrix m1 (matrix() + s1);</div></div><div>=A0 =A0 =
=A0 =A0 break;</div><div>
=A0 =A0 =A0 }</div><div>=A0 =A0 =A0 case 1: {</div><div><div>=A0 =A0 =A0 =
=A0 matrix m2 (matrix() + matrix());</div></div><div>=A0 =A0 =A0 =A0 break;=
</div><div>=A0 =A0 =A0 }</div><div>=A0 =A0 =A0 case 2: {</div><div><div>=A0=
=A0 =A0 =A0 matrix m3 (s1 + s2);</div>
</div><div>=A0 =A0 =A0 =A0 break;</div><div>=A0 =A0 =A0 }</div><div>=A0 =A0=
=A0 case 3: {</div><div><div>=A0 =A0 =A0 =A0 matrix m4 (s1 + matrix());</d=
iv></div><div>=A0 =A0 =A0 =A0 break;</div><div>=A0 =A0 =A0 }</div><div>=A0 =
=A0 } =A0 =A0</div><div>=A0 }</div><div>
}</div></div><div><div><div><br>On Monday, September 16, 2013 9:15:17 AM UT=
C-7, Billy O'Neal wrote:</div></div><blockquote class=3D"gmail_quote" s=
tyle=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">
<div><div><div dir=3D"ltr"><div>Can you post the benchmark code? Not that I=
don't trust you, but 1-2% is well within the margin of error in most c=
ases. In particular, any time you involve IO (e.g. std::cout) that's go=
ing to play havoc with benchmarks.</div>
<div>=A0</div><div>Regarding your code example, that API is poor for 2 reas=
ons:</div><div>1. doing in a way that is exception safe is impossible. The =
way to make it exception safe is just to make copies.</div><div>2. that int=
erface forces creation of a new vector on every call.</div>
<div>3. you have way too many unnecessary moves in that example -- use empl=
ace where possible. If T was something like std::array, move is not cheaper=
than copy.</div><div><div>=A0</div><div>You can fix (1) using something li=
ke:</div>
<div>// Note: I'm no initializer_list expert -- you may need to<br>// h=
ave some kind of wrapper type if it isn't legal to take<br>// a const&a=
mp;.<br>std::vector<matrix><br>add_scalar(std::initializer_<u></u>li<=
u></u>st<matrix const&> matrices,<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 std::initializer_list<int> scalars)<br=
>{<br>=A0 if(matrices.size() !=3D scalars.size()) {<br>=A0=A0=A0 assert(fal=
se && "Matrix scalar size mismatch!");<br>=A0=A0=A0 std::=
terminate(); // Don't throw for things that should terminate!<br>
=A0 }<br>=A0 <br>=A0 // Make exception safe copy:<br>=A0 std::vector<mat=
rix> result(begin(matricies), end(matricies));<br>=A0 auto si =3D begin(=
scalars); // Nothrow<br>=A0 for(matrix& m : result) // Norhrow<br>=A0 {=
<br>=A0=A0=A0=A0 m +=3D *si++; // Nothrow<br>
=A0 }<br>=A0 <br>=A0 return result;<br>}</div></div><div>=A0</div><div>Most=
importantly though, this is a niche case, not a common case. The original =
proposal was trying to support the common case of having a constructor with=
a sink argument. That is a compelling reason to add things to the standard=
-- I'm not sure this is, even in the couple of places where it may mak=
e sense..</div>
</div></div></div><div><div><div><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>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://=
stackoverflow.com/<u></u>users<u></u>/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br></div></div><div class=3D"gmail_quote"><div><div>On Sun, Sep 15, 20=
13 at 4:48 PM, Sumant Tambe <span dir=3D"ltr"><<a>sut...@gmail.com</a>&g=
t;</span> wrote:<br></div></div><blockquote class=3D"gmail_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">
<div><div>
<div dir=3D"ltr"><div>Thanks for the detailed analysis. I agree that in<=
T> is slightly better in some cases and slightly inferior in others. I r=
an a benchmark and saw about 1-2% improvement in performance when using in&=
lt;T> as opposed to the example #2 you proposed. Each run of the benchma=
rk executed all 4 versions (lvalue-lvalue, lvalue-rvalue, rvalue-lvalue, rv=
alue-rvalue) of binary operator+ with equal probability (rand() % 4).=A0<br=
>
</div><div><br></div><div>1 to 2 % performance gain may or may not be "=
;worth" it. People should use their judgement. However, story does not=
end here.</div><div><br></div><div>Binary operator +() provides only one o=
pportunity for in<T> to save a copy. I.e., =A0when the right hand sid=
e object is an rvalue. The in<T> idiom shines the most when there are=
more opportunities to detect rvalues and to exploit them at run-time. So h=
ere is a small function to add scalars to a list of matrices.=A0</div>
<div><br></div><div><div>std::vector<matrix></div><div>add_scalar(std=
::initializer_<u></u>li<u></u>st<in<matrix>> matrices,</div><di=
v>=A0 =A0 =A0 =A0 =A0 =A0std::initializer_list<int> scalars)</div><di=
v>{</div>
<div>
=A0 if(matrices.size() !=3D scalars.size())</div>
<div>=A0 =A0 throw 0;</div><div><br></div><div>=A0 std::vector<matrix>=
; result;</div><div>=A0 result.reserve(matrices.size()<u></u><u></u>);</div=
><div>=A0=A0</div><div>=A0 auto si =3D begin(scalars);</div><div>=A0 for(co=
nst in<matrix> & m : matrices)</div>
<div>=A0 {</div><div>=A0 =A0 =A0if(m.rvalue()) {</div><div>=A0 =A0 =A0 =A0 =
cout << "rvalue matrix\n";</div><div>=A0 =A0 =A0 =A0 result=
..push_back(std::move(m.<u></u>r<u></u>get() +=3D *si));</div><div>=A0 =A0 =
=A0}</div><div>=A0 =A0 =A0else {</div>
<div>
=A0 =A0 =A0 =A0 cout << "lvalue matrix\n";</div>
<div>=A0 =A0 =A0 =A0 result.push_back(std::move(<u></u>mat<u></u>rix(m) +=
=3D *si));</div><div>=A0 =A0 =A0}</div><div>=A0 }</div><div><br></div><div>=
=A0 return result;</div><div>}</div><div><br></div><div>And I call it like =
this:</div><div><div>
<br>
</div>
<div>
matrix s1, s2, s3, s4;</div><div>add_scalar({ s1, s1+s2, s1+s3, s1+s4 }, { =
3, 5, 7, 9});</div></div><div><br></div><div>I tested this code on g++ 4.9 =
and clang 3.3.</div><div><br></div><div>In each use, this function gives fi=
nite but unknown number of opportunities to exploit move-semantics. I'm=
not sure if such a function can be easily implemented using universal refe=
rences. Variadic templates come to mind but two lists of parameters probabl=
y requires separate grouping. I guess it could be done using std::tuple and=
two variadic parameter packs of universal references. But std::make_tuple =
is not as pretty as std::initializer_list.</div>
<div><br></div><div>Surprisingly, in<T> works nicely with initializer=
_list<T>. Initilizer_list does not appear to retain rvalue/lvalue-nes=
s of the original parameter because initializer_list iterator is a pointer =
to consts. In<T>, however, allows the rvalue/lvalue knowledge of the =
original parameter pass through the initializer_list--here is the best part=
--without subverting const-correctness. All member functions in in<T>=
are const. =A0</div>
<div><br></div><div>Thoughts?</div><span><font color=3D"#888888"><div><br><=
/div><div>Sumant</div><br></font></span></div></div></div></div><div><div><=
div><div>
<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></div></div>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<div><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/<u></u>iso<u><=
/u>cpp.org/group/std-<u></u>proposals/</a>.<br>
</div></div></div></blockquote></div><br></div>
</blockquote></div></div><div><div>
<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>std-proposal...@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@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/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div></div>
</blockquote></div></div><div><div class=3D"h5">
<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>
</div></div></blockquote></div><br></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 />
--001a11c2047abf0ad104e68895ed--
.
Author: Alex B <devalexb@gmail.com>
Date: Tue, 17 Sep 2013 09:35:55 -0400
Raw View
--001a11c23c8874299c04e6946601
Content-Type: text/plain; charset=ISO-8859-1
> >Not if Richard's NB comment 12 (http://www.open-std.org/jtc1/
> sc22/wg21/docs/papers/2013/n3733.pdf, search for "US 12") is properly
> resolved - which allows copy / move elision from xvalues.
>
> Fair enough. :) But at the moment it isn't resolved (and isn't resolved
> for C++11), so I'm going to keep giving that advice until it changes.
>
>
Indeed, my example would not be optimal with current C++11. My point was
mainly to point out that concepts will solve most of the problem.
If we want to explore in which way we can make it optimal, first remember
that we are talking about getting features for at least C++17. I think we
can assume there will be an optimal way when we get there. It could be
either the NB comment Xeo mentionned or something else. For example, static
if and/or static conditonnal operator could help here. It could result in
something like this:
template <Sink<matrix> A, Sink<matrix> B>
matrix operator+(A a, B b)
{
return is_mutable_rvalue<A> static ? move(a += b) :
is_mutable_rvalue<B> static ? move(b += a) :
matrix(a) += b;
}
See this thread about static if:
https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bX96720ccmU
--
---
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/.
--001a11c23c8874299c04e6946601
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
<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;p=
adding-left:1ex">
<div dir=3D"ltr"><div><div>>Not if Richard's NB comment 12 (<a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3733.pdf" targ=
et=3D"_blank"><font color=3D"#0066cc">http://www.open-std.org/jtc1/</font><=
font color=3D"#0066cc">sc22/wg21/docs/papers/2013/</font><font color=3D"#00=
66cc">n3733.pdf</font></a>, search for "US 12") is properly resol=
ved - which allows copy / move elision from xvalues.</div>
<div>=A0</div></div><div>Fair enough. :) But at the moment it isn't res=
olved (and isn't resolved for C++11), so I'm going to keep giving t=
hat advice until it changes.</div><div><div>=A0</div></div></div>
</blockquote><div><br></div><div>Indeed, my example would not be optimal wi=
th current C++11. My point was mainly to point out that concepts will solve=
most of the problem.</div><div><br></div><div>If we want to explore in whi=
ch way we can make it optimal, first remember that we are talking about get=
ting features for at least C++17. I think we can assume there will be an op=
timal way when we get there. It could be either the NB comment Xeo mentionn=
ed or something else. For example, static if and/or static conditonnal oper=
ator could help here. It could result in something like this:</div>
<div><br></div><div><div style=3D"font-family:arial,sans-serif;font-size:13=
px"><div><font face=3D"courier new, monospace">template <Sink<matrix&=
gt; A, Sink<matrix> B></font></div><div><font face=3D"courier new,=
monospace">matrix operator+(A a, B b)</font></div>
</div><div style=3D"font-family:arial,sans-serif;font-size:13px"><font face=
=3D"courier new, monospace">{</font></div><div style=3D"font-family:arial,s=
ans-serif;font-size:13px"><font face=3D"courier new, monospace">=A0 =A0retu=
rn=A0</font><span style=3D"font-family:'courier new',monospace">is_=
mutable_rvalue</span><font face=3D"courier new, monospace"><A> static=
? move(a +=3D b) :</font></div>
<div style=3D"font-family:arial,sans-serif;font-size:13px"><font face=3D"co=
urier new, monospace">=A0 =A0 =A0 =A0 =A0=A0</font><span style=3D"font-fami=
ly:'courier new',monospace">is_mutable_rvalue</span><font face=3D"c=
ourier new, monospace"><B> static ? move(b +=3D a) :</font></div>
<div style=3D"font-family:arial,sans-serif;font-size:13px"><font face=3D"co=
urier new, monospace">=A0 =A0 =A0 =A0 =A0 matrix(a) +=3D b;</font></div></d=
iv><div style=3D"font-family:arial,sans-serif;font-size:13px"><font face=3D=
"courier new, monospace">}</font></div>
<div><br></div><div>See this thread about static if:</div><div><a href=3D"h=
ttps://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bX96720cc=
mU">https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bX96=
720ccmU</a><br>
</div></div></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 />
--001a11c23c8874299c04e6946601--
.
Author: Alex B <devalexb@gmail.com>
Date: Thu, 19 Sep 2013 15:16:56 -0400
Raw View
--089e01160938b661bb04e6c16556
Content-Type: text/plain; charset=ISO-8859-1
Something worth mentionning: unless I missed something, none of the
solutions (including mine using concepts) is able to solve the problem when
dealing with *this in a member function.
struct A
{
void member() &;
void member() const &;
void member() &&;
};
--
---
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/.
--089e01160938b661bb04e6c16556
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Something worth mentionning: unless I missed something, no=
ne of the solutions (including mine using concepts) is able to solve the pr=
oblem when dealing with *this in a member function.<div><br></div><div>stru=
ct A</div>
<div>{</div><div>=A0 =A0void member() &;</div><div>=A0 =A0void member()=
const &;<br></div><div>=A0 =A0void member() &&;<br></div><div>=
};</div><div><br></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 />
--089e01160938b661bb04e6c16556--
.
Author: zwvista@msn.com
Date: Fri, 20 Sep 2013 18:02:00 -0700 (PDT)
Raw View
------=_Part_2080_20061569.1379725320164
Content-Type: text/plain; charset=ISO-8859-1
Maybe we should resurrect the idea T&&&.
There was once a C++0x paper about this syntax form which is a generalized
one for the now-called universal reference. Not only can it solve the sink
argument issue here, but also it can solve the problem when dealing with
*this in a member function.
The syntax form may not be important. Perhaps T++ will also do. But we do
need a generalized universal reference for any type, whether templatized or
not.
--
---
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_2080_20061569.1379725320164
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>Maybe we should resurrect the idea T&&&.<d=
iv>There was once a C++0x paper about this syntax form which is a generaliz=
ed one for the now-called universal reference. Not only can it solve the si=
nk argument issue here, but also it can solve the problem when dealing with=
*this in a member function.</div><div>The syntax form may not be important=
.. Perhaps T++ will also do. But we do need a generalized universal referenc=
e for any type, whether templatized or not.</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_2080_20061569.1379725320164--
.
Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Fri, 20 Sep 2013 19:48:25 -0700
Raw View
--047d7b3a9b129dfbc604e6dbd43f
Content-Type: text/plain; charset=ISO-8859-1
T&&& would have still required that the function be a template, and was
functionally equivalent to what is now T&&.
I don't think solving this for member functions is a big deal. Have you
ever been in a situation where you wanted to "generically copy or steal the
guts from" this?
Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com
On Fri, Sep 20, 2013 at 6:02 PM, <zwvista@msn.com> wrote:
>
> Maybe we should resurrect the idea T&&&.
> There was once a C++0x paper about this syntax form which is a generalized
> one for the now-called universal reference. Not only can it solve the sink
> argument issue here, but also it can solve the problem when dealing with
> *this in a member function.
> The syntax form may not be important. Perhaps T++ will also do. But we do
> need a generalized universal reference for any type, whether templatized or
> not.
>
> --
>
> ---
> 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/.
--047d7b3a9b129dfbc604e6dbd43f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>T&&& would have still required that the f=
unction be a template, and was functionally equivalent to what is now T&=
;&.</div><div>=A0</div><div>I don't think solving this for member f=
unctions is a big deal. Have you ever been in a situation where you wanted =
to "generically copy or steal the guts from" this?</div>
</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>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://=
stackoverflow.com/users/82320/billy-oneal</a></div>
<div>Malware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Fri, Sep 20, 2013 at 6:02 PM, <span =
dir=3D"ltr"><<a href=3D"mailto:zwvista@msn.com" target=3D"_blank">zwvist=
a@msn.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><br>Maybe we should resurrect the idea T&&&.<d=
iv>There was once a C++0x paper about this syntax form which is a generaliz=
ed one for the now-called universal reference. Not only can it solve the si=
nk argument issue here, but also it can solve the problem when dealing with=
*this in a member function.</div>
<div>The syntax form may not be important. Perhaps T++ will also do. But we=
do need a generalized universal reference for any type, whether templatize=
d or not.</div></div><div class=3D"HOEnZb"><div class=3D"h5">
<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>
</div></div></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 />
--047d7b3a9b129dfbc604e6dbd43f--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Fri, 19 Sep 2014 07:35:18 -0700 (PDT)
Raw View
------=_Part_2928_1272955419.1411137318370
Content-Type: text/plain; charset=UTF-8
I'm resurrecting this after the awesome talk Herb Sutter gave at CppCon
2014, which covered in depth the issue of "sink" parameters.
In the talk, he showed benchmarks on the various "conventions" used to pass
sink parameters.
*Passing by value, then moving* or *passing by const reference* can become
very inefficient in some situations.
The known solutions are either *creating every possible 2^n combination of
parameters* or *using a template + perfect forwarding.*
Both of these solutions are problematic: the first one requires an
incredible amount of code duplication, the second one forces the programmer
to use templates and it's hard to get right.
*I can't help but feel that this is something that needs to be fixed in the
language.*
Therefore I, again, propose a new *syntactic sugar* argument-passing symbol
that generates code *equivalent to the 2^n solution.*
Writing
struct Example {
std::string s1, s2;
Example(sink std::string mS1, sink std::string mS2) : s1{mS1}, s2{mS2} {
}
};
is equvalent to writing
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} { }
};
The `sink` syntax is just an example - I'm sure it could be much better.
`std::sink<T>` could be used, or T&&&, or something completely different.
Thoughts?
Is this issue being looked into by the language evolution team? Should I
try writing an official proposal and submit it?
--
---
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_2928_1272955419.1411137318370
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'm resurrecting this after the awesome talk Herb Sutter g=
ave at CppCon 2014, which covered in depth the issue of "sink" parameters.<=
br>In the talk, he showed benchmarks on the various "conventions" used to p=
ass sink parameters.<br><br><b>Passing by value, then moving</b> or <b>pass=
ing by const reference</b> can become very inefficient in some situations.<=
div><div><br>The known solutions are either <b>creating every possible 2^n =
combination of parameters</b> or <b>using a template + perfect forward=
ing.</b></div><div>Both of these solutions are problematic: the first one r=
equires an incredible amount of code duplication, the second one forces the=
programmer to use templates and it's hard to get right.</div><div><br></di=
v><div><b><i>I can't help but feel that this is something that needs to be =
fixed in the language.</i></b><br></div><div><br></div><div>Therefore I, ag=
ain, propose a new <b>syntactic sugar</b> argument-passing s=
ymbol that generates code <b>equivalent to the 2^n solution.</b><br><b=
r>Writing</div><div><br></div><div><div class=3D"prettyprint" style=3D"bord=
er: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: =
rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Example</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> std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">string</span><span style=3D"color: #000;" c=
lass=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-b=
y-prettify"> s2</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Example</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">sink 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: #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"> sink 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: #000;" clas=
s=3D"styled-by-prettify"> mS2</span><span style=3D"color: #660;" class=3D"s=
tyled-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</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=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 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-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </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=
: #660;" class=3D"styled-by-prettify">};</span></div></code></div></div><di=
v><br>is equvalent to writing</div></div><div><br></div><div><div class=3D"=
prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: brea=
k-word; background-color: rgb(250, 250, 250);"><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-p=
rettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
Example</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br> 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: #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-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;" class=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-prett=
ify">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">,</sp=
an><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;" 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"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=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"> s1</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</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"> s2</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">move</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">mS2</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)}</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </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 sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #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 style=3D"color: #008;" class=3D=
"styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> mS1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">string</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&&</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> mS2</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: #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"> s1</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">mS1</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">},</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> s2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">move</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #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"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Exa=
mple</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><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;" 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;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> mS2</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</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"> s1</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">move</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">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 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n 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;" 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"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">c=
onst</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">string</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> mS1</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: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">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"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> s1</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"sty=
led-by-prettify">},</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> s2</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">mS2</sp=
an><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: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> <br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">};</span></div></code></div><div><br></div></div><div>The `sink`=
syntax is just an example - I'm sure it could be much better. `std::sink&l=
t;T>` could be used, or T&&&, or something completely differ=
ent.<br><br>Thoughts?<br>Is this issue being looked into by the language ev=
olution team? Should I try writing an official proposal and submit it?</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_2928_1272955419.1411137318370--
.
Author: "'Geoffrey Romer' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Fri, 19 Sep 2014 14:16:30 -0700
Raw View
--001a11c303086540000503719d47
Content-Type: text/plain; charset=UTF-8
On Fri, Sep 19, 2014 at 7:35 AM, Vittorio Romeo <
vittorio.romeo.vee@gmail.com> wrote:
> I'm resurrecting this after the awesome talk Herb Sutter gave at CppCon
> 2014, which covered in depth the issue of "sink" parameters.
> In the talk, he showed benchmarks on the various "conventions" used to
> pass sink parameters.
>
> *Passing by value, then moving* or *passing by const reference* can
> become very inefficient in some situations.
>
As far as I can recall from the talk, the "inefficient" cases for
pass-by-value happen when the function moves its parameter somewhere else
(rather than using it in-place), and either:
1. the parameter type has an expensive move constructor (e.g. std::array)
and the move into the parameter cannot be elided, or
2. the argument is an lvalue, and the argument is large enough that copying
it requires memory allocation, but small enough that the O(N) cost of
copying doesn't dominate the O(1) const of allocation, and the final
destination happens to already have enough memory allocated to hold the
argument value.
Have I forgotten any?
The known solutions are either *creating every possible 2^n combination of
> parameters* or *using a template + perfect forwarding.*
> Both of these solutions are problematic: the first one requires an
> incredible amount of code duplication, the second one forces the programmer
> to use templates and it's hard to get right.
>
The situations above have at least two things in common: they're fairly
unusual, and switching to pass-by-reference will not solve their
performance problems. If #1 is dominating the run-time of a hot loop,
switching to pass-by-reference eliminates only one of the two expensive
move constructor calls, whereas switching to a type with a cheap move
constructor (e.g. unique_ptr) eliminates both of them. As for #2, if your
hot loop is dominated by copying smallish values to destinations that
already contain smallish values, you probably shouldn't be looking for ways
to eliminate the allocation overhead of those copies, but for ways to
eliminate the copying (e.g. string interning, reference-counting). In the
unlikely event that all those copies really are logically necessary, the
situation is so tightly
If your hot loop is dominated by copying smallish values of _all N
parameters of a single function_ to destinations that already contain
smallish values, and N is greater than 2, I'm gonna go out on a limb and
say you need to re-think the life choices that brought you to that pass.
[Credit where it's due: my thinking here is heavily influenced by a
conversation with Chandler Carruth and a few others. Any mistakes are of
course my own]
>
> *I can't help but feel that this is something that needs to be fixed in
> the language.*
>
I can.
I fear this may be an uphill battle after Herb's talk, but I still think
pass-by-value is a perfectly good default choice for 'sink' arguments, and
I'm OK with the fact that you have to do a bit of extra work if you need to
squeeze out that last increment of performance.
>
> Therefore I, again, propose a new *syntactic sugar* argument-passing
> symbol that generates code *equivalent to the 2^n solution.*
>
There's one kind of code to which the above reasoning may not apply:
utility libraries that will be reused without modification across many
application domains (e.g. standard library implementations). In that
situation, you may not know where the hot loop in any given application
will be (although I suspect you could make some pretty good guesses), so
you may need to optimize pervasively. However, I think it's reasonable to
expect maintainers of such libraries to be able to implement perfect
forwarding successfully, and/or to just suck it up and generate the 2^N
overloads. This group of C++ users is very small, but massively
over-represented in places like CppCon and ISO, so we should be wary of
giving excessive weight to their particular concerns.
>
>
> Writing
>
> struct Example {
> std::string s1, s2;
> Example(sink std::string mS1, sink std::string mS2) : s1{mS1}, s2{mS2}
> { }
> };
>
> is equvalent to writing
>
> 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} { }
> };
>
> The `sink` syntax is just an example - I'm sure it could be much better.
> `std::sink<T>` could be used, or T&&&, or something completely different.
>
> Thoughts?
> Is this issue being looked into by the language evolution team? Should I
> try writing an official proposal and submit it?
>
> --
>
> ---
> 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/.
--001a11c303086540000503719d47
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br></div><div class=3D"gmail_e=
xtra"><div class=3D"gmail_quote">On Fri, Sep 19, 2014 at 7:35 AM, Vittorio =
Romeo <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><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex"><div dir=3D"ltr">I'm resurrecting this after the awesome=
talk Herb Sutter gave at CppCon 2014, which covered in depth the issue of =
"sink" parameters.<br>In the talk, he showed benchmarks on the va=
rious "conventions" used to pass sink parameters.<br><br><b>Passi=
ng by value, then moving</b> or <b>passing by const reference</b> can becom=
e very inefficient in some situations.</div></blockquote><div><br></div><di=
v>As far as I can recall from the talk, the "inefficient" cases f=
or pass-by-value happen when the function moves its parameter somewhere els=
e (rather than using it in-place), and either:<br></div><div>1. the paramet=
er type has an expensive move constructor (e.g. std::array) and the move in=
to the parameter cannot be elided, or</div><div>2. the argument is an lvalu=
e, and the argument is large enough that copying it requires memory allocat=
ion, but small enough that the O(N) cost of copying doesn't dominate th=
e O(1) const of allocation, and the final destination happens to already ha=
ve enough memory allocated to hold the argument value.</div><div><br></div>=
<div>Have I forgotten any?</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D=
"ltr"><div><div>The known solutions are either <b>creating every possible 2=
^n combination of parameters</b>=C2=A0or <b>using a template + perfect forw=
arding.</b></div><div>Both of these solutions are problematic: the first on=
e requires an incredible amount of code duplication, the second one forces =
the programmer to use templates and it's hard to get right.</div></div>=
</div></blockquote><div><br></div><div>The situations above have at least t=
wo things in common: they're fairly unusual, and switching to pass-by-r=
eference will not solve their performance problems. If #1 is dominating the=
run-time of a hot loop, switching to pass-by-reference eliminates only one=
of the two expensive move constructor calls, whereas switching to a type w=
ith a cheap move constructor (e.g. unique_ptr) eliminates both of them. As =
for #2, if your hot loop is dominated by copying smallish values to destina=
tions that already contain smallish values, you probably shouldn't be l=
ooking for ways to eliminate the allocation overhead of those copies, but f=
or ways to eliminate the copying (e.g. string interning, reference-counting=
). In the unlikely event that all those copies really are logically necessa=
ry, the situation is so tightly=C2=A0<br></div><div><br></div><div>If your =
hot loop is dominated by copying smallish values of _all N parameters of a =
single function_ to destinations that already contain smallish values, and =
N is greater than 2, I'm gonna go out on a limb and say you need to re-=
think the life choices that brought you to that pass.</div><div><br></div><=
div>[Credit where it's due: my thinking here is heavily influenced by a=
conversation with Chandler Carruth and a few others. Any mistakes are of c=
ourse my own]</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>=
<div><br></div><div><b><i>I can't help but feel that this is something =
that needs to be fixed in the language.</i></b></div></div></div></blockquo=
te><div><br></div><div>I can.</div><div><br></div><div>I fear this may be a=
n uphill battle after Herb's talk, but I still think pass-by-value is a=
perfectly good default choice for 'sink' arguments, and I'm OK=
with the fact that you have to do a bit of extra work if you need to squee=
ze out that last increment of performance.</div><div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><div dir=3D"ltr"><div><div><br></div><div><br></div><div>Therefore I, =
again, propose a new=C2=A0<b>syntactic=C2=A0sugar</b>=C2=A0argument-passing=
symbol that generates code=C2=A0<b>equivalent to the 2^n solution.</b></di=
v></div></div></blockquote><div><br></div><div>There's one kind of code=
to which the above reasoning may not apply: utility libraries that will be=
reused without modification across many application domains (e.g. standard=
library implementations). In that situation, you may not know where the ho=
t loop in any given application will be (although I suspect you could make =
some pretty good guesses), so you may need to optimize pervasively. However=
, I think it's reasonable to expect maintainers of such libraries to be=
able to implement perfect forwarding successfully, and/or to just suck it =
up and generate the 2^N overloads. This group of C++ users is very small, b=
ut massively over-represented in places like CppCon and ISO, so we should b=
e wary of giving excessive weight to their particular concerns.=C2=A0</div>=
<div>=C2=A0</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-l=
eft-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div><br><br>Writin=
g</div><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);=
word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span cl=
ass=3D""><span style=3D"color:rgb(0,0,136)">struct</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Example</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)=
">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 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(0,0,0)"> s1</span><span style=3D"co=
lor:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> s2</span><spa=
n style=3D"color:rgb(102,102,0)">;</span></span><span style=3D"color:rgb(0,=
0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,0,102)">Example=
</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rg=
b(0,0,0)">sink 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(0,0,0)=
"> mS1</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"co=
lor:rgb(0,0,0)"> sink 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:rgb=
(0,0,0)"> mS2</span><span style=3D"color:rgb(102,102,0)">)</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">:</span=
><span style=3D"color:rgb(0,0,0)"> s1</span><span style=3D"color:rgb(102,10=
2,0)">{</span><span style=3D"color:rgb(0,0,0)">mS1</span><span style=3D"col=
or:rgb(102,102,0)">},</span><span style=3D"color:rgb(0,0,0)"> s2</span><spa=
n style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)">m=
S2</span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:=
rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span=
><span style=3D"color:rgb(0,0,0)"> <br></span><span style=3D"color:rgb(102,=
102,0)">};</span></div></code></div></div><div><br>is equvalent to writing<=
/div></div><span class=3D""><div><br></div><div><div style=3D"border:1px so=
lid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)=
"><code><div><span style=3D"color:rgb(0,0,136)">struct</span><span style=3D=
"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Example</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,10=
2,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 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(0,0,0)"> s1</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> s2</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,0,102)">Example<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><span styl=
e=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)">=
&&</span><span style=3D"color:rgb(0,0,0)"> mS1</span><span style=3D=
"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> =C2=A0 =C2=
=A0 =C2=A0std</span><span style=3D"color:rgb(102,102,0)">::</span><span sty=
le=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,102,0)"=
>&&</span><span style=3D"color:rgb(0,0,0)"> mS2</span><span style=
=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> =C2=A0 =
=C2=A0 =C2=A0</span><span style=3D"color:rgb(102,102,0)">:</span><span styl=
e=3D"color:rgb(0,0,0)"> s1</span><span style=3D"color:rgb(102,102,0)">{</sp=
an><span style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,=
102,0)">::</span><span style=3D"color:rgb(0,0,0)">move</span><span style=3D=
"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">mS1</span><=
span style=3D"color:rgb(102,102,0)">)},</span><span style=3D"color:rgb(0,0,=
0)"> s2</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"c=
olor:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan style=3D"color:rgb(0,0,0)">move</span><span style=3D"color:rgb(102,102,=
0)">(</span><span style=3D"color:rgb(0,0,0)">mS2</span><span style=3D"color=
:rgb(102,102,0)">)}</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </sp=
an><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,=
0,0)"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,0,102)">Exampl=
e</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:r=
gb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> 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 style=
=3D"color:rgb(0,0,0)"> mS1</span><span style=3D"color:rgb(102,102,0)">,</sp=
an><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102=
,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><span sty=
le=3D"color:rgb(102,102,0)">&&</span><span style=3D"color:rgb(0,0,0=
)"> mS2</span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"c=
olor:rgb(0,0,0)"> =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:rgb(102,1=
02,0)">:</span><span style=3D"color:rgb(0,0,0)"> s1</span><span style=3D"co=
lor:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)">mS1</span><spa=
n style=3D"color:rgb(102,102,0)">},</span><span style=3D"color:rgb(0,0,0)">=
s2</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color=
:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><span =
style=3D"color:rgb(0,0,0)">move</span><span style=3D"color:rgb(102,102,0)">=
(</span><span style=3D"color:rgb(0,0,0)">mS2</span><span style=3D"color:rgb=
(102,102,0)">)}</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0=
)"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,0,102)">Example</=
span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(=
0,0,0)">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)">&=
amp;&</span><span style=3D"color:rgb(0,0,0)"> mS1</span><span style=3D"=
color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color:rgb(0,0,136)">const</span><span style=
=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rg=
b(102,102,0)">&</span><span style=3D"color:rgb(0,0,0)"> mS2</span><span=
style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb=
(0,0,0)"> s1</span><span style=3D"color:rgb(102,102,0)">{</span><span style=
=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</sp=
an><span style=3D"color:rgb(0,0,0)">move</span><span style=3D"color:rgb(102=
,102,0)">(</span><span style=3D"color:rgb(0,0,0)">mS1</span><span style=3D"=
color:rgb(102,102,0)">)},</span><span style=3D"color:rgb(0,0,0)"> s2</span>=
<span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0=
)">mS2</span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</=
span><span style=3D"color:rgb(0,0,0)"> <br>=C2=A0 =C2=A0 </span><span style=
=3D"color:rgb(102,0,102)">Example</span><span style=3D"color:rgb(102,102,0)=
">(</span><span style=3D"color:rgb(0,0,136)">const</span><span style=3D"col=
or:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><sp=
an style=3D"color:rgb(0,0,136)">string</span><span style=3D"color:rgb(102,1=
02,0)">&</span><span style=3D"color:rgb(0,0,0)"> mS1</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0=
,0)"> 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)">&=
amp;</span><span style=3D"color:rgb(0,0,0)"> mS2</span><span style=3D"color=
:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span sty=
le=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"> s1</s=
pan><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0=
,0,0)">mS1</span><span style=3D"color:rgb(102,102,0)">},</span><span style=
=3D"color:rgb(0,0,0)"> s2</span><span style=3D"color:rgb(102,102,0)">{</spa=
n><span style=3D"color:rgb(0,0,0)">mS2</span><span style=3D"color:rgb(102,1=
02,0)">}</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span st=
yle=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"> <br>=
</span><span style=3D"color:rgb(102,102,0)">};</span></div></code></div><di=
v><br></div></div></span><div>The `sink` syntax is just an example - I'=
m sure it could be much better. `std::sink<T>` could be used, or T&am=
p;&&, or something completely different.<br><br>Thoughts?<br>Is thi=
s issue being looked into by the language evolution team? Should I try writ=
ing an official proposal and submit it?</div></div><div class=3D""><div cla=
ss=3D"h5">
<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 <a href=3D"mailto:std-proposals+unsubscribe@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>
</div></div></blockquote></div><br></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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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 />
--001a11c303086540000503719d47--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 20 Sep 2014 08:42:48 +0800
Raw View
--Apple-Mail=_BD4BE59E-A504-43EB-9F37-059530FDB09D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-09-19, at 10:35 PM, Vittorio Romeo <vittorio.romeo.vee@gmail.com> w=
rote:
> I'm resurrecting this after the awesome talk Herb Sutter gave at CppCon 2=
014, which covered in depth the issue of "sink" parameters.
> In the talk, he showed benchmarks on the various "conventions" used to pa=
ss sink parameters.
What conclusion or recommendation was made in the talk?
> Passing by value, then moving or passing by const reference can become ve=
ry inefficient in some situations.
Well, the goal is to avoid unnecessary copies. Passing by value is optimal =
as long as moving is inexpensive, which holds true in most cases except lar=
ge aggregates (classes with lots of subobjects) like std::array<T, large_si=
ze>.
Passing by value has another downside though, which is that the value of th=
e argument is moved immediately to the parameter as the argument is evaluat=
ed, so the same object can't be used in two arguments.
struct foo {
std::unique_ptr< bar > up;
std::shared_ptr< bar > sp;
};
void f( foo obj, std::shared_ptr< bar > mod ); // does not use obj.sp
void use( foo obj ) {
f( std::move( obj ), obj.sp ); // Unspecified behavior: obj.sp may or m=
ay not be moved-from.
}
Solving this problem requires either more overloads, or a complicated polic=
y in f such as guessing that the subobject should be used if the parameter =
is apparently moved-from, or (worst of all) requiring the user to make a co=
py of the subobject before passing.
Additional overloads are the only good solution, but users might be pushed =
into the other alternatives in trying to avoid changing a documented interf=
ace and ABI. A pass by value function can't coexist as a legacy overload wi=
th pass by reference because it will produce overload ambiguity.
> The known solutions are either creating every possible 2^n combination of=
parameters or using a template + perfect forwarding.
> Both of these solutions are problematic: the first one requires an incred=
ible amount of code duplication, the second one forces the programmer to us=
e templates and it's hard to get right.
It requires std::forward. What's hard about it?
Given that the language + library have a solution already, it might be bett=
er to build on that than to start from scratch.
> I can't help but feel that this is something that needs to be fixed in th=
e language.
>=20
> Therefore I, again, propose a new syntactic sugar argument-passing symbol=
that generates code equivalent to the 2^n solution.
See the recent thread "templating qualifiers," which ran August 27-30.
> struct Example {
> std::string s1, s2;
> Example(sink std::string mS1, sink std::string mS2) : s1{mS1}, s2{mS2=
} { }=20
> };
Brace-initialization isn't enough to invoke a move. You need something that=
definitely signals to the reader, "this object gets invalidated!"
> The `sink` syntax is just an example - I'm sure it could be much better. =
`std::sink<T>` could be used, or T&&&, or something completely different.
My suggestion (so far) is
template< typename std::string const & : && : sink_string1,
typename std::string const & : && : sink_string2 >
Example( sink_string1 mS1, sink_string2 mS2 )
: s1( std::forward< sink_string1 >( mS1 ) )
, s2( std::forward< sink_string2 >( mS2 ) )
{}
Still needs critique, refinement, and formal analysis.
> Thoughts?
> Is this issue being looked into by the language evolution team?
No current progress was mentioned yet in the other thread. I'd be intereste=
d to know, too.
> Should I try writing an official proposal and submit it?
Sure, get the ball rolling!
--=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/.
--Apple-Mail=_BD4BE59E-A504-43EB-9F37-059530FDB09D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;09–19, at 10:35 PM, Vittorio Romeo <<a href=3D"mailto:vittor=
io.romeo.vee@gmail.com">vittorio.romeo.vee@gmail.com</a>> wrote:</div><b=
r class=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D=
"ltr">I'm resurrecting this after the awesome talk Herb Sutter gave at CppC=
on 2014, which covered in depth the issue of "sink" parameters.<br>In the t=
alk, he showed benchmarks on the various "conventions" used to pass sink pa=
rameters.<br></div></blockquote><div><br></div><div>What conclusion or reco=
mmendation was made in the talk?</div><br><blockquote type=3D"cite"><div di=
r=3D"ltr"><b>Passing by value, then moving</b> or <b>passing by const refer=
ence</b> can become very inefficient in some situations.</div></blockquote>=
<div><br></div><div>Well, the goal is to avoid unnecessary copies. Passing =
by value is optimal as long as moving is inexpensive, which holds true in m=
ost cases except large aggregates (classes with lots of subobjects) like <f=
ont face=3D"Courier">std::array<T, large_size></font>.</div><div><br>=
</div><div>Passing by value has another downside though, which is that the =
value of the argument is moved immediately to the parameter as the argument=
is evaluated, so the same object can’t be used in two arguments.</di=
v><div><br></div><div><font face=3D"Courier">struct foo {</font></div><div>=
<font face=3D"Courier"> std::unique_ptr< bar > up;</font=
></div><div><font face=3D"Courier"> std::shared_ptr< bar &g=
t; sp;</font></div><div><font face=3D"Courier">};</font></div><div><font fa=
ce=3D"Courier"><br></font></div><div><font face=3D"Courier">void f( foo obj=
, std::shared_ptr< bar > mod ); // does not use obj.sp</font></div><d=
iv><font face=3D"Courier"><br></font></div><div><font face=3D"Courier">void=
use( foo obj ) {</font></div><div><font face=3D"Courier"> f( =
std::move( obj ), obj.sp ); // Unspecified behavior: obj.sp may or may not =
be moved-from.</font></div><font face=3D"Courier">}</font></div><div><br></=
div><div>Solving this problem requires either more overloads, or a complica=
ted policy in <font face=3D"Courier">f</font> such as guessing that the sub=
object should be used if the parameter is apparently moved-from, or (worst =
of all) requiring the user to make a copy of the subobject before passing.<=
/div><div><br></div><div>Additional overloads are the only good solution, b=
ut users might be pushed into the other alternatives in trying to avoid cha=
nging a documented interface and ABI. A pass by value function can’t =
coexist as a legacy overload with pass by reference because it will produce=
overload ambiguity.</div><div><br><blockquote type=3D"cite"><div dir=3D"lt=
r"><div><div>The known solutions are either <b>creating every possible 2^n =
combination of parameters</b> or <b>using a template + perfect forward=
ing.</b></div><div>Both of these solutions are problematic: the first one r=
equires an incredible amount of code duplication, the second one forces the=
programmer to use templates and it's hard to get right.</div></div></div><=
/blockquote><div><br></div><div>It requires <font face=3D"Courier">std::for=
ward</font>. What’s hard about it?</div><div><br></div><div>Given tha=
t the language + library have a solution already, it might be better to bui=
ld on that than to start from scratch.</div><br><blockquote type=3D"cite"><=
div dir=3D"ltr"><div><div><b><i>I can't help but feel that this is somethin=
g that needs to be fixed in the language.</i></b></div><div><br></div><div>=
Therefore I, again, propose a new <b>syntactic sugar</b> arg=
ument-passing symbol that generates code <b>equivalent to the 2^n solu=
tion.</b><br></div></div></div></blockquote><div><br></div><div>See the rec=
ent thread “templating qualifiers,” which ran August 27-30.</di=
v><br><blockquote type=3D"cite"><div dir=3D"ltr"><div><div><span class=3D"s=
tyled-by-prettify" style=3D"background-color: rgb(250, 250, 250); color: rg=
b(0, 0, 136);">struct</span><span style=3D"background-color: rgb(250, 250, =
250);"> </span><span class=3D"styled-by-prettify" style=3D"background-color=
: rgb(250, 250, 250); color: rgb(102, 0, 102);">Example</span><span style=
=3D"background-color: rgb(250, 250, 250);"> </span><span class=3D"styled-by=
-prettify" style=3D"background-color: rgb(250, 250, 250); color: rgb(102, 1=
02, 0);">{</span></div><div><div class=3D"prettyprint" style=3D"border: 1px=
solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250=
, 250, 250); position: static; z-index: auto;"><code class=3D"prettyprint">=
std<span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</=
span> s1<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span> =
s2<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><br>&nb=
sp; <span style=3D"color: #606;" class=3D"styled-by-prettify">Exampl=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>s=
ink std<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">string</span> mS1<=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span> sink std<=
span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">string</span> mS2<span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span> <span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">:</span> s1<span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span>mS1<span style=3D"color: #660;" =
class=3D"styled-by-prettify">},</span> s2<span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span>mS2<span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span> <span style=3D"color: #660;" class=3D"styled-by-=
prettify">{</span> <span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span> <br><span style=3D"color: #660;" class=3D"styled-by-prettify">};=
</span></code></div></div></div></div></blockquote><div><br></div><div>Brac=
e-initialization isn’t enough to invoke a move. You need something th=
at definitely signals to the reader, “this object gets invalidated!&r=
dquo;</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div><div>The `si=
nk` syntax is just an example - I'm sure it could be much better. `std::sin=
k<T>` could be used, or T&&&, or something completely dif=
ferent.</div></div></div></blockquote><div><br></div><div>My suggestion (so=
far) is</div><div><br></div><div><font face=3D"Courier">template< typen=
ame std::string const & : && : sink_string1,</font></div><div><=
font face=3D"Courier"> typename std::stri=
ng const & : && : sink_string2 ></font></div><div><font face=
=3D"Courier">Example( sink_string1 mS1, sink_string2 mS2 )</font></div><div=
><font face=3D"Courier"> : s1( std::forward< sink_string1 &=
gt;( mS1 ) )</font></div><div><font face=3D"Courier"> , s2( st=
d::forward< sink_string2 >( mS2 ) )</font></div><div><font face=3D"Co=
urier"> {}</font></div><div><br></div><div>Still needs critiqu=
e, refinement, and formal analysis.</div><br><blockquote type=3D"cite"><div=
dir=3D"ltr"><div>Thoughts?<br>Is this issue being looked into by the langu=
age evolution team? </div></div></blockquote><div><br></div><div>No current=
progress was mentioned yet in the other thread. I’d be interested to=
know, too.</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div>Should=
I try writing an official proposal and submit it?</div></div></blockquote>=
<br></div><div>Sure, get the ball rolling!</div><div><br></div></body></htm=
l>
<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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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 />
--Apple-Mail=_BD4BE59E-A504-43EB-9F37-059530FDB09D--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Sep 2014 19:18:17 -0700
Raw View
On Saturday 20 September 2014 08:42:48 David Krauss wrote:
> Well, the goal is to avoid unnecessary copies. Passing by value is optimal
> as long as moving is inexpensive, which holds true in most cases except
> large aggregates (classes with lots of subobjects) like std::array<T,
> large_size>.
Where "large aggregates" is 16 bytes.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 20 Sep 2014 12:42:57 +0800
Raw View
On 2014-09-20, at 10:18 AM, Thiago Macieira <thiago@macieira.org> wrote:
> On Saturday 20 September 2014 08:42:48 David Krauss wrote:
>> Well, the goal is to avoid unnecessary copies. Passing by value is optim=
al
>> as long as moving is inexpensive, which holds true in most cases except
>> large aggregates (classes with lots of subobjects) like std::array<T,
>> large_size>.
>=20
> Where "large aggregates" is 16 bytes.
16 bytes will pass in registers on a 64-bit system in the common ABI, so I =
don't think that's a good rule of thumb. Two registers are slower than one,=
but outside any performance-sensitive critical path, it doesn't matter if =
you're copying 100 bytes. Any memory access is dog-slow if you're not readi=
ng from cache.
Convenience and micro-optimization don't go hand in hand. Suffering the inc=
onvenience of adding all the reference overloads, all the time, just for pe=
rformance, is one's own fault. If it weren't for the correctness issue I me=
ntioned, I'd see a lot less motivation for any new feature.
--=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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 20 Sep 2014 12:46:17 +0800
Raw View
--Apple-Mail=_D63C80EA-5E65-432A-8DC8-CDB5ED3EEC01
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-09-20, at 12:42 PM, David Krauss <potswa@gmail.com> wrote:
> Convenience and micro-optimization don't go hand in hand. Suffering the i=
nconvenience of adding all the reference overloads, all the time, just for =
performance, is one's own fault. If it weren't for the correctness issue I =
mentioned, I'd see a lot less motivation for any new feature.
.... And, for the sake of argument, there are other solutions to the moved-a=
rgument issue, such as specifying that any such move-initialization should =
be evaluated last. This would have the great advantage of fixing legacy cod=
e, albeit probably not 100% of the time.
--=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/.
--Apple-Mail=_D63C80EA-5E65-432A-8DC8-CDB5ED3EEC01
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;09–20, at 12:42 PM, David Krauss <<a href=3D"mailto:potswa@g=
mail.com">potswa@gmail.com</a>> wrote:</div><br class=3D"Apple-interchan=
ge-newline"><blockquote type=3D"cite"><span style=3D"font-family: Helvetica=
; font-size: 12px; font-style: normal; font-variant: normal; font-weight: n=
ormal; letter-spacing: normal; line-height: normal; orphans: auto; text-ali=
gn: start; text-indent: 0px; text-transform: none; white-space: normal; wid=
ows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; =
display: inline !important;">Convenience and micro-optimization don’t=
go hand in hand. Suffering the inconvenience of adding all the reference o=
verloads, all the time, just for performance, is one’s own fault. If =
it weren’t for the correctness issue I mentioned, I’d see a lot=
less motivation for any new feature.</span></blockquote></div><br><div>&he=
llip; And, for the sake of argument, there are other solutions to the moved=
-argument issue, such as specifying that any such move-initialization shoul=
d be evaluated last. This would have the great advantage of fixing legacy c=
ode, albeit probably not 100% of the time.</div><div><br></div></body></htm=
l>
<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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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 />
--Apple-Mail=_D63C80EA-5E65-432A-8DC8-CDB5ED3EEC01--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Sep 2014 22:46:11 -0700
Raw View
On Saturday 20 September 2014 12:42:57 David Krauss wrote:
> > On Saturday 20 September 2014 08:42:48 David Krauss wrote:
> >> Well, the goal is to avoid unnecessary copies. Passing by value is
> >> optimal
> >> as long as moving is inexpensive, which holds true in most cases except
> >> large aggregates (classes with lots of subobjects) like std::array<T,
> >> large_size>.
> >
> >
> >
> > Where "large aggregates" is 16 bytes.
>
> 16 bytes will pass in registers on a 64-bit system in the common ABI, so I
> don't think that's a good rule of thumb. Two registers are slower than one,
> but outside any performance-sensitive critical path, it doesn't matter if
> you're copying 100 bytes. Any memory access is dog-slow if you're not
> reading from cache.
Which is why you should avoid passing by value anything that requires doing
copies to temporary memory due to the ABI. Don't pass by value anything larger
than 16 bytes or which is not trivially copyable.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 20 Sep 2014 14:47:26 +0800
Raw View
--Apple-Mail=_DE5E90A6-8C84-4CA3-AAF8-DD6784BC4E8A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-09-20, at 1:46 PM, Thiago Macieira <thiago@macieira.org> wrote:
> Which is why you should avoid passing by value anything that requires doi=
ng=20
> copies to temporary memory due to the ABI. Don't pass by value anything l=
arger=20
> than 16 bytes or which is not trivially copyable.
The mere fact of copying 24 bytes does not imply bad performance. Duplicati=
ng large functions because the style guide says not to allow such copies wi=
ll likely have a worse performance impact, due to bloat. And with deep inli=
ning, it can be hard to predict what will ultimately be a large function.
Some level of judgment is required, and I prefer to add overloads as they b=
ecome necessary, for correctness or performance.
Also note, my example gains a potential aliasing issue if the shared_ptr su=
bobject is passed by reference. The callee probably expects to be able to m=
ove from one of its parameters without invalidating the other. I've been bi=
tten by this.
--=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/.
--Apple-Mail=_DE5E90A6-8C84-4CA3-AAF8-DD6784BC4E8A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;09–20, at 1:46 PM, Thiago Macieira <<a href=3D"mailto:thiago=
@macieira.org">thiago@macieira.org</a>> wrote:</div><br class=3D"Apple-i=
nterchange-newline"><blockquote type=3D"cite">Which is why you should avoid=
passing by value anything that requires doing <br>copies to temporary memo=
ry due to the ABI. Don't pass by value anything larger <br>than 16 bytes or=
which is not trivially copyable.<br></blockquote><div><br></div></div>The =
mere fact of copying 24 bytes does not imply bad performance. Duplicating l=
arge functions because the style guide says not to allow such copies will l=
ikely have a worse performance impact, due to bloat. And with deep inlining=
, it can be hard to predict what will ultimately be a large function.<div><=
div><br></div><div>Some level of judgment is required, and I prefer to add =
overloads as they become necessary, for correctness or performance.<br><div=
><div><br></div></div></div></div><div>Also note, my example gains a potent=
ial aliasing issue if the <font face=3D"Courier">shared_ptr</font> subobjec=
t is passed by reference. The callee probably expects to be able to move fr=
om one of its parameters without invalidating the other. I’ve been bi=
tten by this.</div><div><br></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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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 />
--Apple-Mail=_DE5E90A6-8C84-4CA3-AAF8-DD6784BC4E8A--
.
Author: Sean Middleditch <sean.middleditch@gmail.com>
Date: Sat, 20 Sep 2014 11:42:37 -0700 (PDT)
Raw View
------=_Part_5017_1965552501.1411238557945
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, September 19, 2014 5:43:06 PM UTC-7, David Krauss wrote:
>
>
> On 2014=E2=80=9309=E2=80=9319, at 10:35 PM, Vittorio Romeo <vittorio....@=
gmail.com=20
> <javascript:>> wrote:
>
> I'm resurrecting this after the awesome talk Herb Sutter gave at CppCon=
=20
> 2014, which covered in depth the issue of "sink" parameters.
> In the talk, he showed benchmarks on the various "conventions" used to=20
> pass sink parameters.
>
>
> What conclusion or recommendation was made in the talk?
>
>
Trying my hand at paraphrasing what I took away (the talk slides are=20
online, of course: see slide 25 in particular from=20
https://github.com/CppCon/CppCon2014/tree/master/Presentations/Back%20to%20=
the%20Basics!%20Essentials%20of%20Modern%20C%2B%2B%20Style)=20
the recommendation is to use the exact same parameter passing conventions=
=20
common to C++98 but with the addition of using an rvalue-reference overload=
=20
for expensive-to-copy/cheap-to-move types that the callee is planning to=20
keep ownership of. Some other considerations and cases were brought up, the=
=20
gist of the argument was to just do things like you did in C++98 and to=20
exceedingly rarely take things by value.
I have counter-points, but most of them are based on (IMO) safer container=
=20
designs than the STL uses (e.g. never ever allow implicit copying of an=20
expensive-to-copy type), so they're rather irrelevant to this conversation=
=20
I think.
--=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/.
------=_Part_5017_1965552501.1411238557945
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, September 19, 2014 5:43:06 PM UTC-7, David Krau=
ss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word"><br><div><div>On 2014=E2=80=9309=E2=80=9319, at 10:35 PM, Vi=
ttorio Romeo <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"as8biN2ygIcJ" onmousedown=3D"this.href=3D'javascript:';return true=
;" onclick=3D"this.href=3D'javascript:';return true;">vittorio....@gmail.co=
m</a>> wrote:</div><br><blockquote type=3D"cite"><div dir=3D"ltr">I'm re=
surrecting this after the awesome talk Herb Sutter gave at CppCon 2014, whi=
ch covered in depth the issue of "sink" parameters.<br>In the talk, he show=
ed benchmarks on the various "conventions" used to pass sink parameters.<br=
></div></blockquote><div><br></div><div>What conclusion or recommendation w=
as made in the talk?</div></div><div><br></div></div></blockquote><div><br>=
</div><div>Trying my hand at paraphrasing what I took away (the talk slides=
are online, of course: see slide 25 in particular from https://github.com/=
CppCon/CppCon2014/tree/master/Presentations/Back%20to%20the%20Basics!%20Ess=
entials%20of%20Modern%20C%2B%2B%20Style) the recommendation is to use the e=
xact same parameter passing conventions common to C++98 but with the additi=
on of using an rvalue-reference overload for expensive-to-copy/cheap-to-mov=
e types that the callee is planning to keep ownership of. Some other consid=
erations and cases were brought up, the gist of the argument was to just do=
things like you did in C++98 and to exceedingly rarely take things by valu=
e.</div><div><br></div><div>I have counter-points, but most of them are bas=
ed on (IMO) safer container designs than the STL uses (e.g. never ever allo=
w implicit copying of an expensive-to-copy type), so they're rather irrelev=
ant to this conversation I think.</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_5017_1965552501.1411238557945--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Sat, 20 Sep 2014 12:00:01 -0700
Raw View
On Saturday 20 September 2014 14:47:26 David Krauss wrote:
> The mere fact of copying 24 bytes does not imply bad performance.
> Duplicating large functions because the style guide says not to allow such
> copies will likely have a worse performance impact, due to bloat. And with
> deep inlining, it can be hard to predict what will ultimately be a large
> function.
>
> Some level of judgment is required, and I prefer to add overloads as they
> become necessary, for correctness or performance.
>
> Also note, my example gains a potential aliasing issue if the shared_ptr
> subobject is passed by reference. The callee probably expects to be able to
> move from one of its parameters without invalidating the other. I've been
> bitten by this.
Maybe we're talking about different things.
I'm mostly thinking of non-inlineable function calls because the function's
body is not available.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 21 Sep 2014 15:50:59 +0800
Raw View
--Apple-Mail=_2B8232BA-C3E0-470F-B6A5-0E892832BDDB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
On 2014-09-21, at 2:42 AM, Sean Middleditch <sean.middleditch@gmail.com> wr=
ote:
> the recommendation is to use the exact same parameter passing conventions=
common to C++98 but with the addition of using an rvalue-reference overloa=
d for expensive-to-copy/cheap-to-move types that the callee is planning to =
keep ownership of.
Pages 23-26 make me queazy. Correctness takes precedence over performance i=
n parameter passing semantics, as in anything else. The question is whether=
a function can safely peek and poke at your argument object, not whether y=
ou wish you didn't have to copy it.
The "expensive to move =3D> pass by lvalue reference" part sticks out like =
a sore thumb. Calling std::move() to pass by rvalue reference uses exactly =
the same ABI mechanics as passing by lvalue reference, and does not incur a=
move construction.
And "f(X) & move ... always incurs a full copy..." is wrong. I'm not sure w=
here std::move() can be applied that makes that correct.
> Some other considerations and cases were brought up, the gist of the argu=
ment was to just do things like you did in C++98 and to exceedingly rarely =
take things by value.
It sounds like I would've had to be there. The slides alone aren't particul=
arly convincing. He benchmarked member assignment instead of initialization=
, then quoted Hinnant saying "Don't blindly assume that the cost of constru=
ction is the same as assignment." The SFINAE in "option 4" seems backwards =
and excludes the char* test, but I think he just didn't actually implement =
it in testing. We really don't see what it is he benchmarked.
Copying a const& parameter to a member is the same operation as copying an =
lvalue argument to a pass-by-value parameter object. There's no way that mo=
ving the parameter into the member is expensive enough to make the differen=
ce shown by the graphs. If he substituted std::swap for move-assignment, wo=
uld that be as expensive?
> I have counter-points, but most of them are based on (IMO) safer containe=
r designs than the STL uses (e.g. never ever allow implicit copying of an e=
xpensive-to-copy type), so they're rather irrelevant to this conversation I=
think.
Well... we're all pretty much in agreement that we want a way to generate r=
eference overloads without hacking perfect forwarding. The question of why =
or when isn't really as important as how. I sort of unfortunately hijacked =
the conversation by questioning the stated motivation, when really I only w=
anted to add an additional motivation regarding correctness, and mention my=
idea for the syntax.
But, I'm surprised that pass-by-value is out of vogue now, so this is inter=
esting to me at least.
--=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/.
--Apple-Mail=_2B8232BA-C3E0-470F-B6A5-0E892832BDDB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"><meta http-equiv=3D"Content-Type" content=3D"text/html cha=
rset=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-n=
bsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2=
014–09–21, at 2:42 AM, Sean Middleditch <<a href=3D"mailto:s=
ean.middleditch@gmail.com">sean.middleditch@gmail.com</a>> wrote:</div><=
br class=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=
=3D"ltr">the recommendation is to use the exact same parameter passing conv=
entions common to C++98 but with the addition of using an rvalue-reference =
overload for expensive-to-copy/cheap-to-move types that the callee is plann=
ing to keep ownership of. </div></blockquote><div><br></div><div>Pages 23-2=
6 make me queazy. Correctness takes precedence over performance in paramete=
r passing semantics, as in anything else. The question is whether a functio=
n can safely peek and poke at your argument object, not whether you wish yo=
u didn’t have to copy it.</div><div><br></div><div>The “expensi=
ve to move =3D> pass by lvalue reference” part sticks out like a s=
ore thumb. Calling std::move() to pass by rvalue reference uses exactly the=
same ABI mechanics as passing by lvalue reference, and does not incur a mo=
ve construction.</div><div><br></div><div>And “f(X) & move &helli=
p; always incurs a full copy…” is wrong. I’m not sure wh=
ere <font face=3D"Courier">std::move()</font> can be applied that makes tha=
t correct.</div><br><blockquote type=3D"cite"><div dir=3D"ltr">Some other c=
onsiderations and cases were brought up, the gist of the argument was to ju=
st do things like you did in C++98 and to exceedingly rarely take things by=
value.</div></blockquote><div><br></div><div>It sounds like I would’=
ve had to be there. The slides alone aren’t particularly convincing. =
He benchmarked member assignment instead of initialization, then quoted Hin=
nant saying “Don’t blindly assume that the cost of co=
nstruction is the same as assignment.” The SFINAE in “option 4&=
rdquo; seems backwards and excludes the char* test, but I think he just did=
n’t actually implement it in testing. We really don’t see what =
it is he benchmarked.</div><div><br></div><div>Copying a <font face=3D"Cour=
ier">const&</font> parameter to a member is the same operation as copyi=
ng an lvalue argument to a pass-by-value parameter object. There’s no=
way that moving the parameter into the member is expensive enough to make =
the difference shown by the graphs. If he substituted <font face=3D"Courier=
">std::swap</font> for move-assignment, would that be as expensive?</div><d=
iv><br></div><blockquote type=3D"cite"><div dir=3D"ltr">I have counter-poin=
ts, but most of them are based on (IMO) safer container designs than the ST=
L uses (e.g. never ever allow implicit copying of an expensive-to-copy type=
), so they're rather irrelevant to this conversation I think.</div></blockq=
uote><br></div><div>Well… we’re all pretty much in agreement t=
hat we want a way to generate reference overloads without hacking perfect f=
orwarding. The question of why or when isn’t really as important as h=
ow. I sort of unfortunately hijacked the conversation by questioning the st=
ated motivation, when really I only wanted to add an additional motivation =
regarding correctness, and mention my idea for the syntax.</div><br><div>Bu=
t, I’m surprised that pass-by-value is out of vogue now, so this is i=
nteresting to me at least.</div><div><br></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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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 />
--Apple-Mail=_2B8232BA-C3E0-470F-B6A5-0E892832BDDB--
.
Author: Sean Middleditch <sean@middleditch.us>
Date: Sun, 21 Sep 2014 16:27:12 -0700
Raw View
On Sun, Sep 21, 2014 at 12:50 AM, David Krauss <potswa@gmail.com> wrote:
> The =E2=80=9Cexpensive to move =3D> pass by lvalue reference=E2=80=9D par=
t sticks out like a
> sore thumb. Calling std::move() to pass by rvalue reference uses exactly =
the
> same ABI mechanics as passing by lvalue reference, and does not incur a m=
ove
> construction.
>
> And =E2=80=9Cf(X) & move =E2=80=A6 always incurs a full copy=E2=80=A6=E2=
=80=9D is wrong. I=E2=80=99m not sure where
> std::move() can be applied that makes that correct.
....
> Copying a const& parameter to a member is the same operation as copying a=
n
> lvalue argument to a pass-by-value parameter object. There=E2=80=99s no w=
ay that
The example used iirc was a large std::array and in general applies to
any type which isn't movable but is copyable (and is expensive to
copy).
--=20
Sean Middleditch
http://seanmiddleditch.com
--=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/.
.
Author: Andy Prowl <andy.prowl@gmail.com>
Date: Tue, 7 Oct 2014 12:50:16 -0700 (PDT)
Raw View
------=_Part_67_2019431105.1412711416811
Content-Type: text/plain; charset=UTF-8
I *think* constrained perfect-forwarding will be made easier with Concepts
TS. For instance, it would be possible to define a concept like the
following one:
template<typename T, typename U>
concept bool IsConvertible = requires()
{
requires std::is_convertible<U, std::decay_t<T>>{};
};
Thanks to terse notation ("abbreviated functions" using the proposal's
terminology), we could then write functions this way:
void foo(IsConvertible<std::string>&&s) { /* ... */ }
The compiler will transform this into:
template<typename T>
requires IsConvertible<T, std::string>
void foo(T&& s) { /* ... */ }
Of course the function would be a template, so the definition must appear
in the header file, but at least the notation will be more readable and
easier to get right.
Kind regards,
Andy
--
---
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_67_2019431105.1412711416811
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I *think* constrained perfect-forwarding will be made easi=
er with Concepts TS. For instance, it would be possible to define a co=
ncept like the following one:<br><br><div class=3D"prettyprint" style=3D"bo=
rder: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color=
: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> T</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">typename</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">concept</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Is</span><font color=
=3D"#660066"><span style=3D"color: #606;" class=3D"styled-by-prettify">Conv=
ertible</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span></font><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> requires</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> requires std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">is_convertible</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">U</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;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">decay_t</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;>{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an></div></code></div><div><br>Thanks to terse notation ("abbreviated funct=
ions" using the proposal's terminology), we could then write functions this=
way:<br><br><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,=
187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><=
code class=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#66=
0066"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">IsConvertible</span><span style=
=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: #008;" cla=
ss=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">>&&</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">s</span><span style=3D"color: #660;" class=3D"s=
tyled-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 style=3D"color: #800;" class=3D"styled-by-prettify">/* ... */</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></font></div></code></div=
><div><br></div>The compiler will transform this into:</div><div><br></div>=
<div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 18=
7); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>requires </span><span style=3D"color: rgb(102, 0, 102); font-=
size: 13.3333330154419px;"><span style=3D"color: #606;" class=3D"styled-by-=
prettify">IsConvertible</span></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</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;" 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"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&&</span><font color=3D"#000000"><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> s</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">/* ... */=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span></font></di=
v></code></div><br>Of course the function would be a template, so the defin=
ition must appear in the header file, but at least the notation will be mor=
e readable and easier to get right.<br><br>Kind regards,<br><br>Andy</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 <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_67_2019431105.1412711416811--
.
Author: Vittorio Romeo <vittorio.romeo.vee@gmail.com>
Date: Sun, 12 Oct 2014 06:46:54 -0700 (PDT)
Raw View
------=_Part_226_1819921051.1413121614128
Content-Type: text/plain; charset=UTF-8
I've written a draft for a proposal (first
time): https://gist.github.com/SuperV1234/7a945b7fa0895bb2ea3c
Is it acceptable? What should be added/changed/removed?
--
---
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_226_1819921051.1413121614128
Content-Type: text/html; charset=UTF-8
<div dir="ltr">I've written a draft for a proposal (first time): https://gist.github.com/SuperV1234/7a945b7fa0895bb2ea3c<br><br><div>Is it acceptable? What should be added/changed/removed?</div></div>
<p></p>
-- <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 email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_226_1819921051.1413121614128--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 12 Oct 2014 16:56:28 +0300
Raw View
On 12 October 2014 16:46, Vittorio Romeo <vittorio.romeo.vee@gmail.com> wrote:
> I've written a draft for a proposal (first time):
> https://gist.github.com/SuperV1234/7a945b7fa0895bb2ea3c
>
> Is it acceptable? What should be added/changed/removed?
I think it would be reasonable to explain what is different from
http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3538.html
and why.
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 12 Oct 2014 22:21:32 +0800
Raw View
On 2014-10-12, at 9:56 PM, Ville Voutilainen <ville.voutilainen@gmail.com> =
wrote:
> I think it would be reasonable to explain what is different from
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3538.html
> and why.
One offers a const reference OR value, the other offers a const reference A=
ND rvalue reference.
I think it would be nice to have a general facility for pseudo-template per=
mutations (well, just combinatorial alternatives actually), with optional s=
yntactic sugar to avoid the template parameter declaration where it could b=
e implicit, and an exception to overload resolution that lets the compiler =
choose if two alternatives tie for the best match.
Perhaps the syntactic sugar isn't strong enough to allow the generated func=
tions to be non-inline, though, which should help stem the combinatorial ex=
plosion.
See the recent thread, "templating qualifiers" opened by Matthew Fioravante=
on Aug 27. The idea still needs development, but it could be more general =
than just a particular sink idiom.
--=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/.
.