Topic: Simple, terse universal forwading for the next decade
Author: mihailnajdenov@gmail.com
Date: Sun, 27 May 2018 04:22:12 -0700 (PDT)
Raw View
------=_Part_25596_294647935.1527420132984
Content-Type: multipart/alternative;
boundary="----=_Part_25597_1893962279.1527420132985"
------=_Part_25597_1893962279.1527420132985
Content-Type: text/plain; charset="UTF-8"
C++11 introduced amazing new core language features in the form of
ownership semantics and perfect forwarding of argument, fixing fundamental
limitations, previously present in the language.
Considering these features are now close to 10 years old I strongly believe
they should be promoted to language level.
But there is more, I also believe the separation b/w the two is not needed *in
practice. *
And not only in practice, but there is also a common semantic core to both
- they both implement the notion of *giving. *This is very unique and
strong relation, not to be ignored.
Yes, both implement the notion differently (pass-through vs transfer), but
both are the action of giving up, saying goodbye to the object you have.
After that you can not longer use it - you don't have it - unless you
recreate it (reassign it).
Lets get back to the practice. Because the action is final - you cant use
both on one instance. You *either* move *or* forward.
When to use move and when forward is surprisingly non-trivial to learn,
*especially* considering no error will be reported in messing up either
case.
This is VERY confusing to a beginner and even an experienced programmer can
get confused - there are quite a few stackoverflow questions "Is this a
forwarding reference", pointing to something with && on its type.
Lastly, forward itself have massive problems of its own, from verbosity,
through confusing mandatory template param, to usability in extremely
limited context.
*Universal Forwarding *
Lest exploit the common base notion of both move and forward. The notion of
giving up the object.
*Just for illustration* lets call it give and *just for illustration* make
it a function.
The idea is simple - give expands to move in all cases *except* when called
with forwarding reference, then it expands to forward.
*That's it.*
Then you give the object in all cases when you need to forward it to
someone else
void f(const String& s)
{
auto list = s.split();
// use list
memberfunc(give(list)); //< moves
}
template<class T>
deltype(auto) func(T&& a)
{
return func_impl(give(a)); //< will forward - argument is "forwarding
reference"
}
void func2(String&& a, auto&& b)
{
auto o = construct(give(b)); //< will forward
o.call(give(a)); //< will move
// Note the user can get these wrong; give will not!
}
You get the idea - give is smart enough to do the right thing.
Of course this is not possible without compiler support, but is it *im*possible?
I really doubt.
The compiler should have all the information. And the only "new"
information it *really* needs is
__is_template_argment(decltype(arg))
This is - to know the type is not part of the function original
declaration, but substituted when the function was created on the call site.
But this information is already there, isn't is? "function was called with
T = std::string" and so on?
With that in hand, all we need is - is it decorated in any way besides &&,
and this info already available and trivial to get in the form of
is_reference and is_const and so on.
*Terse*
As said the function give is just for illustration.
Of not lesser importance is to be minimize verbosity. In the case of move -
because it is often used in repeated fashion like
Class::Class(String s, Funstion f)
: _s(std::move(s))
, _f(std::move(f)
{}
ClassB::ClassB(ClassB&& o)
: _a(std::move(o.a))
, _c(std::move(o.c)
{}
As for forward, how verbose it can get, especially considering it is always
used in template context, which is verbose enough on its own!
No tool is better to remove verbosity then an operator, and once unified
(move and forward), it will be MUCH easier to come up with a good operator
symbol(s) (*Just for illustration, lets call it @*).
Seriously, there are plenty of options* once we no longer need to worry
"what about forward" or "what about move"!* We use ONE operator for BOTH !
Using an op has one additional benefit - it is legal for it to hide
compiler magic, unlike some odd, compiler-helped function.
Lastly, I believe it is best, if the operator is *postfix*.
Here is why:
auto f(QImage img)
{
return process(img@.mirrored()); //< calls QImage&& QImage::mirrored() &&
overload, reusing the instance
}
auto cally = [](auto&& func, auto&& arg)
{
return func@(arg@); //< forwards both the callable and the arguments,
with absolutely minimal syntax overhead
};
*Conclusion *
move and forward are here to stay for good, but they are just in their
first iteration now. They should evolve.
I believe, streamlining the notion of forwarding an object will simplify
both learning and using the language.
Thank You
MihailNaydenov
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082%40isocpp.org.
------=_Part_25597_1893962279.1527420132985
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><br></div><div>C++11 introduced amazing new core lang=
uage features in the form of ownership semantics and perfect forwarding of =
argument, fixing fundamental limitations, previously present in the languag=
e.</div><div><br></div><div>Considering these features are now close to 10 =
years old I strongly believe they should be promoted to language level.</di=
v><div><br></div><div>But there is more, I also believe the separation b/w =
the two is not needed <i>in practice.=C2=A0</i></div><div><i><br></i></div>=
<div>And not only in practice, but there is also a common semantic core to =
both - they both implement the notion of <i>giving. </i>This is very unique=
and strong relation, not to be ignored.</div><div>Yes, both implement the =
notion differently (pass-through vs transfer), but both are the action of g=
iving up, saying goodbye to the object you have.</div><div><font face=3D"ar=
ial,sans-serif">After that you can not longer use it - you don't have i=
t - unless you recreate it (reassign it).=C2=A0</font></div><div><font face=
=3D"arial,sans-serif"><br></font></div><div><font face=3D"arial,sans-serif"=
>Lets get back to the practice. Because the action is final - you cant use =
both on one instance. You <i>either</i> <font face=3D"courier new,monospace=
">move</font> <i>or</i> <font face=3D"courier new,monospace">forward</font>=
..</font></div><div><font face=3D"arial,sans-serif"><br></font></div><div>Wh=
en to use <font face=3D"courier new,monospace">move</font> and when <font f=
ace=3D"courier new,monospace">forward</font> is surprisingly non-trivial to=
learn, <i>especially</i>=C2=A0 considering no error will be reported in me=
ssing up either case.=C2=A0</div><div>This is VERY confusing to a beginner =
and even an experienced programmer can get confused - there are quite a few=
stackoverflow questions "Is this a forwarding reference", pointi=
ng to something with && on its type.</div><div><br></div><div>Lastl=
y, forward itself have massive problems of its own, from verbosity, through=
confusing mandatory template param, to usability in extremely limited cont=
ext.</div><div><br></div><div><br></div><div><b>Universal Forwarding=C2=A0<=
/b></div><div><b><br></b></div><div>Lest exploit the common base notion of =
both move and forward. The notion of giving up the object.=C2=A0</div><div>=
<i><br></i></div><div><i>Just for illustration</i> lets call it <font face=
=3D"courier new,monospace">give</font> and <i>just for illustration</i> mak=
e it a function.</div><div><br></div><div>The idea is simple - <font face=
=3D"courier new,monospace">give</font> expands to <font face=3D"courier new=
,monospace">move</font> in all cases <i>except</i> when called with forward=
ing reference, then it expands to <font face=3D"courier new,monospace">forw=
ard</font>.</div><div><br></div><div><b><i>That's it.</i></b></div><div=
><b></b><i></i><br></div><div>Then you <font face=3D"courier new,monospace"=
>give</font><font face=3D"arial,sans-serif"> the object in all cases when y=
ou need to forward it to someone else</font></div><div><br></div><div><font=
face=3D"courier new,monospace">void f(const String& s)</font></div><di=
v><font face=3D"courier new,monospace">{</font></div><div><font face=3D"cou=
rier new,monospace">=C2=A0 auto list =3D s.split();</font></div><div><font =
face=3D"courier new,monospace"><br></font></div><div><font face=3D"courier =
new,monospace">=C2=A0 // use list</font></div><div><font face=3D"courier ne=
w,monospace">=C2=A0=C2=A0</font></div><div><font face=3D"courier new,monosp=
ace">=C2=A0 memberfunc(give(list)); //< moves</font></div><div><font fac=
e=3D"courier new,monospace">}</font></div><div><font face=3D"courier new,mo=
nospace"><br></font></div><div><font face=3D"courier new,monospace">templat=
e<class T></font></div><div><font face=3D"courier new,monospace">delt=
ype(auto) func(T&& a)</font></div><div><font face=3D"courier new,mo=
nospace">{</font></div><div><font face=3D"courier new,monospace"><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: courier new,monospace; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; orphans: 2; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
normal; word-spacing: 0px;">=C2=A0return func_impl(give(a)); //< will f=
orward - argument is "forwarding reference"</span><br></font></di=
v><div><font face=3D"courier new,monospace">}</font></div><div><font face=
=3D"courier new,monospace"><br></font></div><div><font face=3D"courier new,=
monospace"><div style=3D"background-color: transparent; border-bottom-color=
: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bor=
der-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%=
; border-image-source: none; border-image-width: 1; border-left-color: rgb(=
34, 34, 34); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; =
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width=
: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; f=
ont-variant: normal; font-weight: 400; letter-spacing: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;"><font face=3D"courier new,monospace" style=3D"border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px;">void func2(String&& a, auto&& b)</font></div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D=
"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</font></div=
><div style=3D"background-color: transparent; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helve=
tica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; ma=
rgin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bot=
tom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-ali=
gn: left; text-decoration: none; text-indent: 0px; text-transform: none; -w=
ebkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><fon=
t face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, =
34); border-bottom-style: none; border-bottom-width: 0px; border-image-outs=
et: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image=
-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); b=
order-left-style: none; border-left-width: 0px; border-right-color: rgb(34,=
34, 34); border-right-style: none; border-right-width: 0px; border-top-col=
or: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-=
bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-=
bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><spa=
n style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, =
34); border-bottom-style: none; border-bottom-width: 0px; border-image-outs=
et: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image=
-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); b=
order-left-style: none; border-left-width: 0px; border-right-color: rgb(34,=
34, 34); border-right-style: none; border-right-width: 0px; border-top-col=
or: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: =
rgb(34, 34, 34); display: inline; float: none; font-family: courier new,mon=
ospace; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; mar=
gin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-l=
eft: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;">=C2=A0 auto o =3D const=
ruct(give(b)); //< will forward=C2=A0</span></font></div><div style=3D"m=
argin: 0px; padding: 0px; border: 0px rgb(34, 34, 34); border-image: none; =
text-align: left; color: rgb(34, 34, 34); text-transform: none; text-indent=
: 0px; letter-spacing: normal; font-size: 13px; font-variant: normal; word-=
spacing: 0px; white-space: normal; orphans: 2; -webkit-text-stroke-width: 0=
px; background-color: transparent;"><font face=3D"courier new,monospace" st=
yle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pad=
ding-right: 0px; padding-top: 0px;"><span style=3D"background-color: transp=
arent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; f=
loat: none; font-family: courier new,monospace; font-size: 13px; font-style=
: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; m=
argin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; or=
phans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddi=
ng-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; tex=
t-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wor=
d-spacing: 0px;">=C2=A0 o.call(give(a)); //< will move</span></font></di=
v><div style=3D"margin: 0px; padding: 0px; border: 0px rgb(34, 34, 34); bor=
der-image: none; text-align: left; color: rgb(34, 34, 34); text-transform: =
none; text-indent: 0px; letter-spacing: normal; font-size: 13px; font-varia=
nt: normal; word-spacing: 0px; white-space: normal; orphans: 2; -webkit-tex=
t-stroke-width: 0px; background-color: transparent;"><font face=3D"courier =
new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;"><b></b><i></i><u></u><=
sub></sub><sup></sup><strike></strike><br></font></div><div style=3D"margin=
: 0px; padding: 0px; border: 0px rgb(34, 34, 34); border-image: none; text-=
align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px=
; letter-spacing: normal; font-size: 13px; font-variant: normal; word-spaci=
ng: 0px; white-space: normal; orphans: 2; -webkit-text-stroke-width: 0px; b=
ackground-color: transparent;"><font face=3D"courier new,monospace" style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;">=C2=A0 // Note the user can get these wron=
g; give will not!</font><br></div></font><div style=3D"background-color: tr=
ansparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none;=
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: str=
etch; border-image-slice: 100%; border-image-source: none; border-image-wid=
th: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-=
left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: n=
one; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top=
-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &=
amp;quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-siz=
e: 13px; font-style: normal; font-variant: normal; font-weight: 400; letter=
-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; te=
xt-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white=
-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospace"><f=
ont face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}<=
/font></font></div><div style=3D"background-color: transparent; border-bott=
om-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: =
0px; border-image-outset: 0; border-image-repeat: stretch; border-image-sli=
ce: 100%; border-image-source: none; border-image-width: 1; border-left-col=
or: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; borde=
r-right-color: rgb(34, 34, 34); border-right-style: none; border-right-widt=
h: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-t=
op-width: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quo=
t;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: n=
ormal; font-variant: normal; font-weight: 400; letter-spacing: normal; marg=
in-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orpha=
ns: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-=
top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;"><font face=3D"courier new,monospace"><br></font></div></div><=
div style=3D"text-align: left;"><font face=3D"arial,sans-serif">You get the=
idea - <font face=3D"courier new,monospace">give</font> is smart enough to=
do the right thing.</font></div><div style=3D"text-align: left;"><font fac=
e=3D"arial,sans-serif"><br></font></div><b></b><i></i><u></u><sub></sub><su=
p></sup><strike></strike><font face=3D"courier new,monospace"></font><div><=
font face=3D"arial,sans-serif"></font><br></div><div>Of course this is not =
possible without compiler support, but is it <i>im</i>possible? I really do=
ubt.</div><div>The compiler should have all the information. And the only &=
quot;new" information it <i>really</i> needs is</div><div><br></div><d=
iv>__is_template_argment(decltype(arg))</div><div><br></div><div>This is - =
to know the type is not part of the function original declaration, but subs=
tituted when the function was created on the call site.</div><div><br></div=
><div>But this information is already there, isn't is? "function w=
as called with T =3D std::string" and so on?</div><div><br></div><div>=
With that in hand, all we need is - is it decorated in any way besides &=
;&, and this info already available and trivial to get in the form of <=
font face=3D"courier new,monospace">is_reference</font> and<font face=3D"co=
urier new,monospace"> is_const </font>and so on.=C2=A0<br></div><div><br></=
div><div><b>Terse</b></div><div><b><br></b></div><div>As said the function =
<font face=3D"courier new,monospace">give</font> is just for illustration.=
=C2=A0</div><div>Of not lesser importance is to be minimize verbosity. In t=
he case of move - because it is often used in repeated fashion like=C2=A0</=
div><div><br></div><div><font face=3D"courier new,monospace">Class::Class(S=
tring s, Funstion f)</font></div><div><font face=3D"courier new,monospace">=
=C2=A0: _s(std::move(s))</font></div><div><font face=3D"courier new,monospa=
ce">=C2=A0, _f(std::move(f)</font></div><div><font face=3D"courier new,mono=
space">{}</font></div><div><font face=3D"courier new,monospace">=C2=A0</fon=
t></div><div><div style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&am=
p;quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal;=
font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2;=
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;"><font face=3D"courier new,monospace">ClassB::ClassB(ClassB&&=
; o)</font></div><div style=3D"background-color: transparent; border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans=
: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><font face=3D"courier new,monospace">=C2=A0: _a(std::move(o.a))=
</font></div><div style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&am=
p;quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal;=
font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2;=
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;"><font face=3D"courier new,monospace">=C2=A0, _c(std::move(o.c)</fon=
t></div><div style=3D"background-color: transparent; border-bottom-color: r=
gb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border=
-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; b=
order-image-source: none; border-image-width: 1; border-left-color: rgb(34,=
34, 34); border-left-style: none; border-left-width: 0px; border-right-col=
or: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bor=
der-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0=
px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quo=
t;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font=
-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: =
0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padd=
ing-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; t=
ext-align: left; text-decoration: none; text-indent: 0px; text-transform: n=
one; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px=
;"><font face=3D"courier new,monospace">{}</font></div><b></b><i></i><u></u=
><sub></sub><sup></sup><strike></strike><font face=3D"courier new,monospace=
"></font><br></div><div>As for <font face=3D"courier new,monospace">forward=
</font>, how verbose it can get, especially considering it is always used i=
n template context, which is verbose enough on its own!=C2=A0</div><div><b>=
</b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><div>No =
tool is better to remove verbosity then an operator, and once unified (move=
and forward), it will be MUCH easier to come up with a good operator symbo=
l(s) <span style=3D"display: inline !important; float: none; background-col=
or: transparent; color: rgb(34, 34, 34); font-family: "Arial",&qu=
ot;Helvetica",sans-serif; font-size: 13px; font-style: normal; font-va=
riant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">(<=
/span><i style=3D"background-attachment: scroll; background-clip: border-bo=
x; background-color: transparent; background-image: none; background-origin=
: padding-box; background-position-x: 0%; background-position-y: 0%; backgr=
ound-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: italic; font-variant:=
normal; font-weight: 400; height: auto; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: =
0px; orphans: 2; overflow: visible; overflow-x: visible; overflow-y: visibl=
e; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top:=
0px; text-align: left; text-decoration: none; text-indent: 0px; text-trans=
form: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spaci=
ng: 0px;">J<span style=3D"background-color: transparent; border-bottom-colo=
r: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(34, 34, 34); border-left-style: none; border-left-width: 0px; border-right=
-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px;=
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-widt=
h: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-size: 13=
px; font-variant: normal; font-weight: 400; letter-spacing: normal; margin-=
bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans:=
2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top=
: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tran=
sform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spac=
ing: 0px;">ust for illustration, lets call it @</span></i><span style=3D"di=
splay: inline !important; float: none; background-color: transparent; color=
: rgb(34, 34, 34); font-family: "Arial","Helvetica",san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wi=
dth: 0px; white-space: normal; word-spacing: 0px;">)</span>.</div><div><br>=
</div><div>Seriously, there are plenty of options<i> once we no longer need=
to worry "what about forward" or "what about move"!</i=
> We use ONE operator for BOTH !</div><div><br></div><div>Using an op has o=
ne additional benefit - it is legal for it to hide compiler magic, unlike s=
ome odd, compiler-helped function.=C2=A0</div><div><br></div><div>Lastly, I=
believe it is best, if the operator is <i>postfix</i>.=C2=A0</div><div><b>=
</b><i></i><u></u><sub></sub><sup></sup><strike></strike><i></i><br></div><=
div>Here is why:</div><div><font face=3D"courier new,monospace"></font><br>=
</div><div><div style=3D"background-color: transparent; border-bottom-color=
: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bor=
der-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%=
; border-image-source: none; border-image-width: 1; border-left-color: rgb(=
34, 34, 34); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; =
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width=
: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; f=
ont-variant: normal; font-weight: 400; letter-spacing: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;"><font face=3D"courier new,monospace">auto f(QImage img)</font></div><=
div style=3D"background-color: transparent; border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; -web=
kit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font =
face=3D"courier new,monospace">{</font></div><div style=3D"background-color=
: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: n=
one; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat:=
stretch; border-image-slice: 100%; border-image-source: none; border-image=
-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bor=
der-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-styl=
e: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border=
-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-famil=
y: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0=
px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; pa=
dding-right: 0px; padding-top: 0px; text-align: left; text-decoration: none=
; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; w=
hite-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospace=
">=C2=A0 return process(img@.mirrored()); //< calls QImage&& QIm=
age::<span style=3D"display: inline !important; float: none; background-col=
or: transparent; color: rgb(34, 34, 34); font-family: courier new,monospace=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: =
none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0p=
x; white-space: normal; word-spacing: 0px;">mirrored</span>() && ov=
erload, reusing the instance</font></div><div style=3D"background-color: tr=
ansparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none;=
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: str=
etch; border-image-slice: 100%; border-image-source: none; border-image-wid=
th: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-=
left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: n=
one; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top=
-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &=
amp;quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-siz=
e: 13px; font-style: normal; font-variant: normal; font-weight: 400; letter=
-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; te=
xt-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white=
-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospace">}<=
/font></div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><fo=
nt face=3D"courier new,monospace"></font><br></div><div><font face=3D"couri=
er new,monospace">auto cally =3D [](auto&& func, auto&& arg=
)=C2=A0</font></div><div><font face=3D"courier new,monospace">{<br></font><=
/div><font face=3D"courier new,monospace">=C2=A0 return func@(arg@); //<=
forwards both the callable and the arguments, with absolutely minimal synt=
ax overhead<br>};</font><br><div><br></div><div><b>Conclusion=C2=A0</b></di=
v><div><b><br></b></div><div><font face=3D"courier new,monospace">move</fon=
t> and <font face=3D"courier new,monospace">forward</font> are here to stay=
for good, but they are just in their first iteration now. They should evol=
ve.</div><div>I believe, streamlining the notion of forwarding an object wi=
ll simplify both learning and using the language.=C2=A0</div><div><br></div=
><div><br></div><div>Thank You</div><div>MihailNaydenov</div><div><br></div=
><div><br></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></s=
trike><b></b><b></b><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082=
%40isocpp.org</a>.<br />
------=_Part_25597_1893962279.1527420132985--
------=_Part_25596_294647935.1527420132984--
.
Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Sun, 27 May 2018 13:28:17 +0200
Raw View
--000000000000322c14056d2e4c02
Content-Type: text/plain; charset="UTF-8"
Seems like really good idea!
On Sun, May 27, 2018 at 1:22 PM, <mihailnajdenov@gmail.com> wrote:
>
> C++11 introduced amazing new core language features in the form of
> ownership semantics and perfect forwarding of argument, fixing fundamental
> limitations, previously present in the language.
>
> Considering these features are now close to 10 years old I strongly
> believe they should be promoted to language level.
>
> But there is more, I also believe the separation b/w the two is not needed *in
> practice. *
>
> And not only in practice, but there is also a common semantic core to both
> - they both implement the notion of *giving. *This is very unique and
> strong relation, not to be ignored.
> Yes, both implement the notion differently (pass-through vs transfer), but
> both are the action of giving up, saying goodbye to the object you have.
> After that you can not longer use it - you don't have it - unless you
> recreate it (reassign it).
>
> Lets get back to the practice. Because the action is final - you cant use
> both on one instance. You *either* move *or* forward.
>
> When to use move and when forward is surprisingly non-trivial to learn,
> *especially* considering no error will be reported in messing up either
> case.
> This is VERY confusing to a beginner and even an experienced programmer
> can get confused - there are quite a few stackoverflow questions "Is this a
> forwarding reference", pointing to something with && on its type.
>
> Lastly, forward itself have massive problems of its own, from verbosity,
> through confusing mandatory template param, to usability in extremely
> limited context.
>
>
> *Universal Forwarding *
>
> Lest exploit the common base notion of both move and forward. The notion
> of giving up the object.
>
> *Just for illustration* lets call it give and *just for illustration*
> make it a function.
>
> The idea is simple - give expands to move in all cases *except* when
> called with forwarding reference, then it expands to forward.
>
> *That's it.*
>
> Then you give the object in all cases when you need to forward it to
> someone else
>
> void f(const String& s)
> {
> auto list = s.split();
>
> // use list
>
> memberfunc(give(list)); //< moves
> }
>
> template<class T>
> deltype(auto) func(T&& a)
> {
> return func_impl(give(a)); //< will forward - argument is "forwarding
> reference"
> }
>
> void func2(String&& a, auto&& b)
> {
> auto o = construct(give(b)); //< will forward
> o.call(give(a)); //< will move
>
> // Note the user can get these wrong; give will not!
> }
>
> You get the idea - give is smart enough to do the right thing.
>
>
> Of course this is not possible without compiler support, but is it *im*possible?
> I really doubt.
> The compiler should have all the information. And the only "new"
> information it *really* needs is
>
> __is_template_argment(decltype(arg))
>
> This is - to know the type is not part of the function original
> declaration, but substituted when the function was created on the call site.
>
> But this information is already there, isn't is? "function was called with
> T = std::string" and so on?
>
> With that in hand, all we need is - is it decorated in any way besides &&,
> and this info already available and trivial to get in the form of
> is_reference and is_const and so on.
>
> *Terse*
>
> As said the function give is just for illustration.
> Of not lesser importance is to be minimize verbosity. In the case of move
> - because it is often used in repeated fashion like
>
> Class::Class(String s, Funstion f)
> : _s(std::move(s))
> , _f(std::move(f)
> {}
>
> ClassB::ClassB(ClassB&& o)
> : _a(std::move(o.a))
> , _c(std::move(o.c)
> {}
>
> As for forward, how verbose it can get, especially considering it is
> always used in template context, which is verbose enough on its own!
>
> No tool is better to remove verbosity then an operator, and once unified
> (move and forward), it will be MUCH easier to come up with a good operator
> symbol(s) (*Just for illustration, lets call it @*).
>
> Seriously, there are plenty of options* once we no longer need to worry
> "what about forward" or "what about move"!* We use ONE operator for BOTH !
>
> Using an op has one additional benefit - it is legal for it to hide
> compiler magic, unlike some odd, compiler-helped function.
>
> Lastly, I believe it is best, if the operator is *postfix*.
>
> Here is why:
>
> auto f(QImage img)
> {
> return process(img@.mirrored()); //< calls QImage&& QImage::mirrored()
> && overload, reusing the instance
> }
>
> auto cally = [](auto&& func, auto&& arg)
> {
> return func@(arg@); //< forwards both the callable and the arguments,
> with absolutely minimal syntax overhead
> };
>
> *Conclusion *
>
> move and forward are here to stay for good, but they are just in their
> first iteration now. They should evolve.
> I believe, streamlining the notion of forwarding an object will simplify
> both learning and using the language.
>
>
> Thank You
> MihailNaydenov
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-
> bf15-3670b2727082%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
Yours sincerely
Artur Czajkowski
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANPOWsf4DKAM13xV%3DgK99B%3DTiLYRQGD1_WYX53jyvujvm8aTWw%40mail.gmail.com.
--000000000000322c14056d2e4c02
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Seems like really good idea!</div><div class=3D"gmail_extr=
a"><br><div class=3D"gmail_quote">On Sun, May 27, 2018 at 1:22 PM, <span d=
ir=3D"ltr"><<a href=3D"mailto:mihailnajdenov@gmail.com" target=3D"_blank=
">mihailnajdenov@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"><div><br></div><div>C++11 introduced amazing new c=
ore language features in the form of ownership semantics and perfect forwar=
ding of argument, fixing fundamental limitations, previously present in the=
language.</div><div><br></div><div>Considering these features are now clos=
e to 10 years old I strongly believe they should be promoted to language le=
vel.</div><div><br></div><div>But there is more, I also believe the separat=
ion b/w the two is not needed <i>in practice.=C2=A0</i></div><div><i><br></=
i></div><div>And not only in practice, but there is also a common semantic =
core to both - they both implement the notion of <i>giving. </i>This is ver=
y unique and strong relation, not to be ignored.</div><div>Yes, both implem=
ent the notion differently (pass-through vs transfer), but both are the act=
ion of giving up, saying goodbye to the object you have.</div><div><font fa=
ce=3D"arial,sans-serif">After that you can not longer use it - you don'=
t have it - unless you recreate it (reassign it).=C2=A0</font></div><div><f=
ont face=3D"arial,sans-serif"><br></font></div><div><font face=3D"arial,san=
s-serif">Lets get back to the practice. Because the action is final - you c=
ant use both on one instance. You <i>either</i> <font face=3D"courier new,m=
onospace">move</font> <i>or</i> <font face=3D"courier new,monospace">forwar=
d</font>.</font></div><div><font face=3D"arial,sans-serif"><br></font></div=
><div>When to use <font face=3D"courier new,monospace">move</font> and when=
<font face=3D"courier new,monospace">forward</font> is surprisingly non-tr=
ivial to learn, <i>especially</i>=C2=A0 considering no error will be report=
ed in messing up either case.=C2=A0</div><div>This is VERY confusing to a b=
eginner and even an experienced programmer can get confused - there are qui=
te a few stackoverflow questions "Is this a forwarding reference"=
, pointing to something with && on its type.</div><div><br></div><d=
iv>Lastly, forward itself have massive problems of its own, from verbosity,=
through confusing mandatory template param, to usability in extremely limi=
ted context.</div><div><br></div><div><br></div><div><b>Universal Forwardin=
g=C2=A0</b></div><div><b><br></b></div><div>Lest exploit the common base no=
tion of both move and forward. The notion of giving up the object.=C2=A0</d=
iv><div><i><br></i></div><div><i>Just for illustration</i> lets call it <fo=
nt face=3D"courier new,monospace">give</font> and <i>just for illustration<=
/i> make it a function.</div><div><br></div><div>The idea is simple - <font=
face=3D"courier new,monospace">give</font> expands to <font face=3D"courie=
r new,monospace">move</font> in all cases <i>except</i> when called with fo=
rwarding reference, then it expands to <font face=3D"courier new,monospace"=
>forward</font>.</div><div><br></div><div><b><i>That's it.</i></b></div=
><div><b></b><i></i><br></div><div>Then you <font face=3D"courier new,monos=
pace">give</font><font face=3D"arial,sans-serif"> the object in all cases w=
hen you need to forward it to someone else</font></div><div><br></div><div>=
<font face=3D"courier new,monospace">void f(const String& s)</font></di=
v><div><font face=3D"courier new,monospace">{</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 auto list =3D s.split();</font></div><div=
><font face=3D"courier new,monospace"><br></font></div><div><font face=3D"c=
ourier new,monospace">=C2=A0 // use list</font></div><div><font face=3D"cou=
rier new,monospace">=C2=A0=C2=A0</font></div><div><font face=3D"courier new=
,monospace">=C2=A0 memberfunc(give(list)); //< moves</font></div><div><f=
ont face=3D"courier new,monospace">}</font></div><div><font face=3D"courier=
new,monospace"><br></font></div><div><font face=3D"courier new,monospace">=
template<class T></font></div><div><font face=3D"courier new,monospac=
e">deltype(auto) func(T&& a)</font></div><div><font face=3D"courier=
new,monospace">{</font></div><div><font face=3D"courier new,monospace"><sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:courier new,monospace;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">=C2=A0return func_impl(give(a)); //< wil=
l forward - argument is "forwarding reference"</span><br></font><=
/div><div><font face=3D"courier new,monospace">}</font></div><div><font fac=
e=3D"courier new,monospace"><br></font></div><div><font face=3D"courier new=
,monospace"><div><font face=3D"courier new,monospace" style=3D"border-botto=
m-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;bord=
er-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px;bo=
rder-right-color:rgb(34,34,34);border-right-style:none;border-right-width:0=
px;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width:0p=
x;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;padding=
-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px">void func2(=
String&& a, auto&& b)</font></div><div><font face=3D"courie=
r new,monospace" style=3D"border-bottom-color:rgb(34,34,34);border-bottom-s=
tyle:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-le=
ft-style:none;border-left-width:0px;border-right-color:rgb(34,34,34);border=
-right-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);bor=
der-top-style:none;border-top-width:0px;margin-bottom:0px;margin-left:0px;m=
argin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-=
right:0px;padding-top:0px">{</font></div><div><font face=3D"courier new,mon=
ospace" style=3D"border-bottom-color:rgb(34,34,34);border-bottom-style:none=
;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-style:=
none;border-left-width:0px;border-right-color:rgb(34,34,34);border-right-st=
yle:none;border-right-width:0px;border-top-color:rgb(34,34,34);border-top-s=
tyle:none;border-top-width:0px;margin-bottom:0px;margin-left:0px;margin-rig=
ht:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px=
;padding-top:0px"><span style=3D"background-color:transparent;border-bottom=
-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;borde=
r-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px;bor=
der-right-color:rgb(34,34,34);border-right-style:none;border-right-width:0p=
x;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width:0px=
;color:rgb(34,34,34);display:inline;float:none;font-family:courier new,mono=
space;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;=
letter-spacing:normal;margin-bottom:0px;margin-left:0px;margin-right:0px;ma=
rgin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-=
top:0px;text-align:left;text-decoration:none;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px">=C2=A0 auto o =3D construct(give=
(b)); //< will forward=C2=A0</span></font></div><div style=3D"margin:0px=
;padding:0px;border:0px rgb(34,34,34);text-align:left;color:rgb(34,34,34);t=
ext-transform:none;text-indent:0px;letter-spacing:normal;font-size:13px;fon=
t-variant:normal;word-spacing:0px;white-space:normal;background-color:trans=
parent"><font face=3D"courier new,monospace" style=3D"border-bottom-color:r=
gb(34,34,34);border-bottom-style:none;border-bottom-width:0px;border-left-c=
olor:rgb(34,34,34);border-left-style:none;border-left-width:0px;border-righ=
t-color:rgb(34,34,34);border-right-style:none;border-right-width:0px;border=
-top-color:rgb(34,34,34);border-top-style:none;border-top-width:0px;margin-=
bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0=
px;padding-left:0px;padding-right:0px;padding-top:0px"><span style=3D"backg=
round-color:transparent;border-bottom-color:rgb(34,34,34);border-bottom-sty=
le:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left=
-style:none;border-left-width:0px;border-right-color:rgb(34,34,34);border-r=
ight-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);borde=
r-top-style:none;border-top-width:0px;color:rgb(34,34,34);display:inline;fl=
oat:none;font-family:courier new,monospace;font-size:13px;font-style:normal=
;font-variant:normal;font-weight:400;letter-spacing:normal;margin-bottom:0p=
x;margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;paddin=
g-left:0px;padding-right:0px;padding-top:0px;text-align:left;text-decoratio=
n:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px">=C2=A0 o.call(give(a)); //< will move</span></font></div><div style=
=3D"margin:0px;padding:0px;border:0px rgb(34,34,34);text-align:left;color:r=
gb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font=
-size:13px;font-variant:normal;word-spacing:0px;white-space:normal;backgrou=
nd-color:transparent"><font face=3D"courier new,monospace" style=3D"border-=
bottom-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px=
;border-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0=
px;border-right-color:rgb(34,34,34);border-right-style:none;border-right-wi=
dth:0px;border-top-color:rgb(34,34,34);border-top-style:none;border-top-wid=
th:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;pa=
dding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px"><b></b=
><i></i><u></u><sub></sub><sup></sup><strike></strike><br></font></div><div=
style=3D"margin:0px;padding:0px;border:0px rgb(34,34,34);text-align:left;c=
olor:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:norma=
l;font-size:13px;font-variant:normal;word-spacing:0px;white-space:normal;ba=
ckground-color:transparent"><font face=3D"courier new,monospace" style=3D"b=
order-bottom-color:rgb(34,34,34);border-bottom-style:none;border-bottom-wid=
th:0px;border-left-color:rgb(34,34,34);border-left-style:none;border-left-w=
idth:0px;border-right-color:rgb(34,34,34);border-right-style:none;border-ri=
ght-width:0px;border-top-color:rgb(34,34,34);border-top-style:none;border-t=
op-width:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:=
0px;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px">=
=C2=A0 // Note the user can get these wrong; give will not!</font><br></div=
></font><div><font face=3D"courier new,monospace"><font face=3D"courier new=
,monospace" style=3D"border-bottom-color:rgb(34,34,34);border-bottom-style:=
none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-st=
yle:none;border-left-width:0px;border-right-color:rgb(34,34,34);border-righ=
t-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);border-t=
op-style:none;border-top-width:0px;margin-bottom:0px;margin-left:0px;margin=
-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-right=
:0px;padding-top:0px">}</font></font></div><div><font face=3D"courier new,m=
onospace"><br></font></div></div><div style=3D"text-align:left"><font face=
=3D"arial,sans-serif">You get the idea - <font face=3D"courier new,monospac=
e">give</font> is smart enough to do the right thing.</font></div><div styl=
e=3D"text-align:left"><font face=3D"arial,sans-serif"><br></font></div><b><=
/b><i></i><u></u><sub></sub><sup></sup><strike></strike><font face=3D"couri=
er new,monospace"></font><div><font face=3D"arial,sans-serif"></font><br></=
div><div>Of course this is not possible without compiler support, but is it=
<i>im</i>possible? I really doubt.</div><div>The compiler should have all =
the information. And the only "new" information it <i>really</i> =
needs is</div><div><br></div><div>__is_template_argment(<wbr>decltype(arg))=
</div><div><br></div><div>This is - to know the type is not part of the fun=
ction original declaration, but substituted when the function was created o=
n the call site.</div><div><br></div><div>But this information is already t=
here, isn't is? "function was called with T =3D std::string" =
and so on?</div><div><br></div><div>With that in hand, all we need is - is =
it decorated in any way besides &&, and this info already available=
and trivial to get in the form of <font face=3D"courier new,monospace">is_=
reference</font> and<font face=3D"courier new,monospace"> is_const </font>a=
nd so on.=C2=A0<br></div><div><br></div><div><b>Terse</b></div><div><b><br>=
</b></div><div>As said the function <font face=3D"courier new,monospace">gi=
ve</font> is just for illustration.=C2=A0</div><div>Of not lesser importanc=
e is to be minimize verbosity. In the case of move - because it is often us=
ed in repeated fashion like=C2=A0</div><div><br></div><div><font face=3D"co=
urier new,monospace">Class::Class(String s, Funstion f)</font></div><div><f=
ont face=3D"courier new,monospace">=C2=A0: _s(std::move(s))</font></div><di=
v><font face=3D"courier new,monospace">=C2=A0, _f(std::move(f)</font></div>=
<div><font face=3D"courier new,monospace">{}</font></div><div><font face=3D=
"courier new,monospace">=C2=A0</font></div><div><div><font face=3D"courier =
new,monospace">ClassB::ClassB(ClassB&& o)</font></div><div><font fa=
ce=3D"courier new,monospace">=C2=A0: _a(std::move(o.a))</font></div><div><f=
ont face=3D"courier new,monospace">=C2=A0, _c(std::move(o.c)</font></div><d=
iv><font face=3D"courier new,monospace">{}</font></div><b></b><i></i><u></u=
><sub></sub><sup></sup><strike></strike><font face=3D"courier new,monospace=
"></font><br></div><div>As for <font face=3D"courier new,monospace">forward=
</font>, how verbose it can get, especially considering it is always used i=
n template context, which is verbose enough on its own!=C2=A0</div><div><b>=
</b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><div>No =
tool is better to remove verbosity then an operator, and once unified (move=
and forward), it will be MUCH easier to come up with a good operator symbo=
l(s) <span style=3D"display:inline!important;float:none;background-color:tr=
ansparent;color:rgb(34,34,34);font-family:"Arial","Helvetica=
",sans-serif;font-size:13px;font-style:normal;font-variant:normal;font=
-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">(</spa=
n><i>J<span style=3D"background-color:transparent;border-bottom-color:rgb(3=
4,34,34);border-bottom-style:none;border-bottom-width:0px;border-left-color=
:rgb(34,34,34);border-left-style:none;border-left-width:0px;border-right-co=
lor:rgb(34,34,34);border-right-style:none;border-right-width:0px;border-top=
-color:rgb(34,34,34);border-top-style:none;border-top-width:0px;color:rgb(3=
4,34,34);display:inline;float:none;font-size:13px;font-variant:normal;font-=
weight:400;letter-spacing:normal;margin-bottom:0px;margin-left:0px;margin-r=
ight:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0=
px;padding-top:0px;text-align:left;text-decoration:none;text-indent:0px;tex=
t-transform:none;white-space:normal;word-spacing:0px">ust for illustration,=
lets call it @</span></i><span style=3D"display:inline!important;float:non=
e;background-color:transparent;color:rgb(34,34,34);font-family:"Arial&=
quot;,"Helvetica",sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text=
-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px">)</span>.</div><div><br></div><div>Seriously, there are plen=
ty of options<i> once we no longer need to worry "what about forward&q=
uot; or "what about move"!</i> We use ONE operator for BOTH !</di=
v><div><br></div><div>Using an op has one additional benefit - it is legal =
for it to hide compiler magic, unlike some odd, compiler-helped function.=
=C2=A0</div><div><br></div><div>Lastly, I believe it is best, if the operat=
or is <i>postfix</i>.=C2=A0</div><div><b></b><i></i><u></u><sub></sub><sup>=
</sup><strike></strike><i></i><br></div><div>Here is why:</div><div><font f=
ace=3D"courier new,monospace"></font><br></div><div><div><font face=3D"cour=
ier new,monospace">auto f(QImage img)</font></div><div><font face=3D"courie=
r new,monospace">{</font></div><div><font face=3D"courier new,monospace">=
=C2=A0 return process(img@.mirrored()); //< calls QImage&& QImag=
e::<span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:courier new,monospace;font-size:13p=
x;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:norm=
al;text-align:left;text-decoration:none;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px">mirrored</span>() && overload=
, reusing the instance</font></div><div><font face=3D"courier new,monospace=
">}</font></div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike=
><font face=3D"courier new,monospace"></font><br></div><div><font face=3D"c=
ourier new,monospace">auto cally =3D [](auto&& func, auto&&=
arg)=C2=A0</font></div><div><font face=3D"courier new,monospace">{<br></fo=
nt></div><font face=3D"courier new,monospace">=C2=A0 return func@(arg@); //=
< forwards both the callable and the arguments, with absolutely minimal =
syntax overhead<br>};</font><br><div><br></div><div><b>Conclusion=C2=A0</b>=
</div><div><b><br></b></div><div><font face=3D"courier new,monospace">move<=
/font> and <font face=3D"courier new,monospace">forward</font> are here to =
stay for good, but they are just in their first iteration now. They should =
evolve.</div><div>I believe, streamlining the notion of forwarding an objec=
t will simplify both learning and using the language.=C2=A0</div><div><br><=
/div><div><br></div><div>Thank You</div><div>MihailNaydenov</div><span clas=
s=3D"HOEnZb"><font color=3D"#888888"><div><br></div><div><br></div><div><b>=
</b><i></i><u></u><sub></sub><sup></sup><strike></strike><b></b><b></b><br>=
</div></font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/8054=
8757-8a42-499a-<wbr>bf15-3670b2727082%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br><div clas=
s=3D"gmail_signature" data-smartmail=3D"gmail_signature">Yours sincerely<br=
>Artur Czajkowski</div>
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANPOWsf4DKAM13xV%3DgK99B%3DTiLYRQGD1=
_WYX53jyvujvm8aTWw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANPOWsf4DKAM=
13xV%3DgK99B%3DTiLYRQGD1_WYX53jyvujvm8aTWw%40mail.gmail.com</a>.<br />
--000000000000322c14056d2e4c02--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 27 May 2018 14:34:10 +0300
Raw View
On 27 May 2018 at 14:28, Arthur Tchaikovsky <atch.cpp@gmail.com> wrote:
> Seems like really good idea!
See http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0644r1.html.
That didn't get consensus.
>
> On Sun, May 27, 2018 at 1:22 PM, <mihailnajdenov@gmail.com> wrote:
>>
>>
>> C++11 introduced amazing new core language features in the form of
>> ownership semantics and perfect forwarding of argument, fixing fundamental
>> limitations, previously present in the language.
>>
>> Considering these features are now close to 10 years old I strongly
>> believe they should be promoted to language level.
>>
>> But there is more, I also believe the separation b/w the two is not needed
>> in practice.
>>
>> And not only in practice, but there is also a common semantic core to both
>> - they both implement the notion of giving. This is very unique and strong
>> relation, not to be ignored.
>> Yes, both implement the notion differently (pass-through vs transfer), but
>> both are the action of giving up, saying goodbye to the object you have.
>> After that you can not longer use it - you don't have it - unless you
>> recreate it (reassign it).
>>
>> Lets get back to the practice. Because the action is final - you cant use
>> both on one instance. You either move or forward.
>>
>> When to use move and when forward is surprisingly non-trivial to learn,
>> especially considering no error will be reported in messing up either case.
>> This is VERY confusing to a beginner and even an experienced programmer
>> can get confused - there are quite a few stackoverflow questions "Is this a
>> forwarding reference", pointing to something with && on its type.
>>
>> Lastly, forward itself have massive problems of its own, from verbosity,
>> through confusing mandatory template param, to usability in extremely
>> limited context.
>>
>>
>> Universal Forwarding
>>
>> Lest exploit the common base notion of both move and forward. The notion
>> of giving up the object.
>>
>> Just for illustration lets call it give and just for illustration make it
>> a function.
>>
>> The idea is simple - give expands to move in all cases except when called
>> with forwarding reference, then it expands to forward.
>>
>> That's it.
>>
>> Then you give the object in all cases when you need to forward it to
>> someone else
>>
>> void f(const String& s)
>> {
>> auto list = s.split();
>>
>> // use list
>>
>> memberfunc(give(list)); //< moves
>> }
>>
>> template<class T>
>> deltype(auto) func(T&& a)
>> {
>> return func_impl(give(a)); //< will forward - argument is "forwarding
>> reference"
>> }
>>
>> void func2(String&& a, auto&& b)
>> {
>> auto o = construct(give(b)); //< will forward
>> o.call(give(a)); //< will move
>>
>> // Note the user can get these wrong; give will not!
>> }
>>
>> You get the idea - give is smart enough to do the right thing.
>>
>>
>> Of course this is not possible without compiler support, but is it
>> impossible? I really doubt.
>> The compiler should have all the information. And the only "new"
>> information it really needs is
>>
>> __is_template_argment(decltype(arg))
>>
>> This is - to know the type is not part of the function original
>> declaration, but substituted when the function was created on the call site.
>>
>> But this information is already there, isn't is? "function was called with
>> T = std::string" and so on?
>>
>> With that in hand, all we need is - is it decorated in any way besides &&,
>> and this info already available and trivial to get in the form of
>> is_reference and is_const and so on.
>>
>> Terse
>>
>> As said the function give is just for illustration.
>> Of not lesser importance is to be minimize verbosity. In the case of move
>> - because it is often used in repeated fashion like
>>
>> Class::Class(String s, Funstion f)
>> : _s(std::move(s))
>> , _f(std::move(f)
>> {}
>>
>> ClassB::ClassB(ClassB&& o)
>> : _a(std::move(o.a))
>> , _c(std::move(o.c)
>> {}
>>
>> As for forward, how verbose it can get, especially considering it is
>> always used in template context, which is verbose enough on its own!
>>
>> No tool is better to remove verbosity then an operator, and once unified
>> (move and forward), it will be MUCH easier to come up with a good operator
>> symbol(s) (Just for illustration, lets call it @).
>>
>> Seriously, there are plenty of options once we no longer need to worry
>> "what about forward" or "what about move"! We use ONE operator for BOTH !
>>
>> Using an op has one additional benefit - it is legal for it to hide
>> compiler magic, unlike some odd, compiler-helped function.
>>
>> Lastly, I believe it is best, if the operator is postfix.
>>
>> Here is why:
>>
>> auto f(QImage img)
>> {
>> return process(img@.mirrored()); //< calls QImage&& QImage::mirrored()
>> && overload, reusing the instance
>> }
>>
>> auto cally = [](auto&& func, auto&& arg)
>> {
>> return func@(arg@); //< forwards both the callable and the arguments,
>> with absolutely minimal syntax overhead
>> };
>>
>> Conclusion
>>
>> move and forward are here to stay for good, but they are just in their
>> first iteration now. They should evolve.
>> I believe, streamlining the notion of forwarding an object will simplify
>> both learning and using the language.
>>
>>
>> Thank You
>> MihailNaydenov
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/80548757-8a42-499a-bf15-3670b2727082%40isocpp.org.
>
>
>
>
> --
> Yours sincerely
> Artur Czajkowski
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANPOWsf4DKAM13xV%3DgK99B%3DTiLYRQGD1_WYX53jyvujvm8aTWw%40mail.gmail.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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUYW7z7DuH8Zt6GCFDNL3qrmKk1YqsRf%3D9OWRWBs9gg8gQ%40mail.gmail.com.
.
Author: mihailnajdenov@gmail.com
Date: Sun, 27 May 2018 05:00:13 -0700 (PDT)
Raw View
------=_Part_25613_1370015714.1527422413647
Content-Type: multipart/alternative;
boundary="----=_Part_25614_1021035783.1527422413647"
------=_Part_25614_1021035783.1527422413647
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Sunday, May 27, 2018 at 2:34:13 PM UTC+3, Ville Voutilainen wrote:
>
> On 27 May 2018 at 14:28, Arthur Tchaikovsky <atch...@gmail.com=20
> <javascript:>> wrote:=20
> > Seems like really good idea!=20
>
> See http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0644r1.html.=20
> That didn't get consensus.=20
> =E2=80=A6
>
"EWG sympathized with the desire to eliminate this boilerplate, but felt=20
that >>, or indeed any other unary operator, would be too confusing of a=20
syntax, especially when occuring after an =3D in a lambda init-capture (e.g=
.. [foo=3D>>foo](...){=20
.... }). EWG was willing to entertain a keyword instead, but the best people=
=20
could come up with was fwdexpr and that didn=E2=80=99t have consensus; as a=
result,=20
the future of this proposal is uncertain."=20
These are not serous objections, besides it is a prefix-ness of the=20
operator, which introduces most of problems.
a =3D >>b // confusing indeed
(>>x)(>>d) // not ideal by far, needs brackets and more brackets is=
=20
the last thing we need in C++
p((>>img).mirrored())
A postfix operator eliminates these issues. It probably introduces new=20
ones, nothing fatal I hope.
In any case, the unification is of interest here, syntax aside. (As said=20
with unification the syntax will be easier to come up with!)
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b72b930a-9b57-42c4-b1f5-8ce036d4d9c4%40isocpp.or=
g.
------=_Part_25614_1021035783.1527422413647
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, May 27, 2018 at 2:34:13 PM UTC+3, Ville=
Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 27 May 2=
018 at 14:28, Arthur Tchaikovsky <<a onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"SNr0HVw2BgAJ">atch...@gmail.com</a>> wrote:
<br>> Seems like really good idea!
<br>
<br>See <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\x3dh=
ttp%3A%2F%2Fopen-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2017%2Fp064=
4r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHhQdLJhseZYtrN6WG9-QcjOp9b=
tw';return true;" onclick=3D"this.href=3D'http://www.google.com/url=
?q\x3dhttp%3A%2F%2Fopen-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2017=
%2Fp0644r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHhQdLJhseZYtrN6WG9-=
QcjOp9btw';return true;" href=3D"http://open-std.org/JTC1/SC22/WG21/doc=
s/papers/2017/p0644r1.html" target=3D"_blank" rel=3D"nofollow">http://open-=
std.org/JTC1/SC22/<wbr>WG21/docs/papers/2017/p0644r1.<wbr>html</a>.
<br>That didn't get consensus.
<br>=E2=80=A6<br></blockquote><div><br></div><div>"<span style=3D"disp=
lay: inline !important; float: none; background-color: transparent; color: =
rgb(20, 20, 18); font-family: "Source Sans Pro",Helvetica,sans-se=
rif; font-size: 16px; font-style: normal; font-variant: normal; font-weight=
: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoratio=
n: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width:=
0px; white-space: normal; word-spacing: 0px;">EWG sympathized with the des=
ire to eliminate this boilerplate, but felt that </span><code style=3D"back=
ground-color: transparent; box-sizing: border-box; color: rgb(20, 20, 18); =
font-family: monospace,serif; font-size: 14px; font-style: normal; font-var=
iant: normal; font-weight: 400; letter-spacing: normal; -ms-hyphens: none; =
orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text=
-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word=
-spacing: 0px;">>></code><span style=3D"display: inline !important; f=
loat: none; background-color: transparent; color: rgb(20, 20, 18); font-fam=
ily: "Source Sans Pro",Helvetica,sans-serif; font-size: 16px; fon=
t-style: normal; font-variant: normal; font-weight: 400; letter-spacing: no=
rmal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px=
; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal=
; word-spacing: 0px;">, or indeed any other unary operator, would be too co=
nfusing of a syntax, especially when occuring after an </span><code style=
=3D"background-color: transparent; box-sizing: border-box; color: rgb(20, 2=
0, 18); font-family: monospace,serif; font-size: 14px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; -ms-hyphens=
: none; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">=3D</code><span style=3D"display: inline !important=
; float: none; background-color: transparent; color: rgb(20, 20, 18); font-=
family: "Source Sans Pro",Helvetica,sans-serif; font-size: 16px; =
font-style: normal; font-variant: normal; font-weight: 400; letter-spacing:=
normal; orphans: 2; text-align: left; text-decoration: none; text-indent: =
0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: nor=
mal; word-spacing: 0px;"> in a lambda init-capture (e.g. </span><code style=
=3D"background-color: transparent; box-sizing: border-box; color: rgb(20, 2=
0, 18); font-family: monospace,serif; font-size: 14px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; -ms-hyphens=
: none; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">[foo=3D>>foo](...){ ... }</code><span style=
=3D"display: inline !important; float: none; background-color: transparent;=
color: rgb(20, 20, 18); font-family: "Source Sans Pro",Helvetica=
,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; fon=
t-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-d=
ecoration: none; text-indent: 0px; text-transform: none; -webkit-text-strok=
e-width: 0px; white-space: normal; word-spacing: 0px;">). EWG was willing t=
o entertain a keyword instead, but the best people could come up with was <=
/span><code style=3D"background-color: transparent; box-sizing: border-box;=
color: rgb(20, 20, 18); font-family: monospace,serif; font-size: 14px; fon=
t-style: normal; font-variant: normal; font-weight: 400; letter-spacing: no=
rmal; -ms-hyphens: none; orphans: 2; text-align: left; text-decoration: non=
e; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; =
white-space: normal; word-spacing: 0px;">fwdexpr</code><span style=3D"displ=
ay: inline !important; float: none; background-color: transparent; color: r=
gb(20, 20, 18); font-family: "Source Sans Pro",Helvetica,sans-ser=
if; font-size: 16px; font-style: normal; font-variant: normal; font-weight:=
400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;"> and that didn=E2=80=99t have=
consensus; as a result, the future of this proposal is uncertain.</span>&q=
uot;=C2=A0</div><div><br></div><div><font face=3D"arial,sans-serif">These a=
re not serous objections, besides it is a prefix-ness of the operator, whic=
h introduces most of problems.</font></div><div><font face=3D"arial,sans-se=
rif"><br></font></div><div><font face=3D"courier new,monospace">a =3D >&=
gt;b =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 // confusing indeed</font></d=
iv><div><font face=3D"courier new,monospace">(>>x)(>>d) =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 // not ideal by far, needs brackets=C2=A0<span style=
=3D"display: inline !important; float: none; background-color: transparent;=
color: rgb(34, 34, 34); font-family: courier new,monospace; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; orphans: 2; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;">and more brackets is the last thing we need in =
C++</span></font></div><div><font face=3D"courier new,monospace">p((>>=
;img).mirrored())</font></div><div><br></div><div><font face=3D"arial,sans-=
serif">A postfix operator eliminates these issues. It probably introduces n=
ew ones, nothing fatal I hope.</font></div><div><font face=3D"arial,sans-se=
rif"><br></font></div><div><font face=3D"arial,sans-serif">In any case, the=
unification is of interest here, syntax aside. (As said with unification t=
he syntax will be easier to come up with!)</font></div><div><font face=3D"c=
ourier new,monospace"><font face=3D"arial,sans-serif"></font><br></font></d=
iv></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b72b930a-9b57-42c4-b1f5-8ce036d4d9c4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b72b930a-9b57-42c4-b1f5-8ce036d4d9c4=
%40isocpp.org</a>.<br />
------=_Part_25614_1021035783.1527422413647--
------=_Part_25613_1370015714.1527422413647--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 27 May 2018 06:47:46 -0700 (PDT)
Raw View
------=_Part_20392_518174215.1527428866727
Content-Type: multipart/alternative;
boundary="----=_Part_20393_465585470.1527428866728"
------=_Part_20393_465585470.1527428866728
Content-Type: text/plain; charset="UTF-8"
On Sunday, May 27, 2018 at 7:22:13 AM UTC-4, mihailn...@gmail.com wrote:
>
>
> C++11 introduced amazing new core language features in the form of
> ownership semantics and perfect forwarding of argument, fixing fundamental
> limitations, previously present in the language.
>
> Considering these features are now close to 10 years old I strongly
> believe they should be promoted to language level.
>
> But there is more, I also believe the separation b/w the two is not needed *in
> practice. *
>
> And not only in practice, but there is also a common semantic core to both
> - they both implement the notion of *giving. *
>
When you move an object into something else, there is a broad expectation
that the object has been moved from once that expression completes. This
means you are free to reuse the old object, so long as you reset it to
known state first. When you forward something, you *don't know* its current
state. You don't know if it was moved from or not. You don't even know if
it's OK for you to manipulate the object, because you don't know why you
were *given* the kind of reference you were.
In forwarding cases, you were given something for one purpose: to *forward
it*. In move cases, things are a lot less abstract. Forwarding is something
you do in a completely different context than moving. The two constructs
should not be combined.
This is very unique and strong relation, not to be ignored.
> Yes, both implement the notion differently (pass-through vs transfer), but
> both are the action of giving up, saying goodbye to the object you have.
> After that you can not longer use it - you don't have it - unless you
> recreate it (reassign it).
>
> Lets get back to the practice. Because the action is final - you cant use
> both on one instance. You *either* move *or* forward.
>
> When to use move and when forward is surprisingly non-trivial to learn,
> *especially* considering no error will be reported in messing up either
> case.
> This is VERY confusing to a beginner and even an experienced programmer
> can get confused - there are quite a few stackoverflow questions "Is this a
> forwarding reference", pointing to something with && on its type.
>
> Lastly, forward itself have massive problems of its own, from verbosity,
> through confusing mandatory template param, to usability in extremely
> limited context.
>
>
> *Universal Forwarding *
>
> Lest exploit the common base notion of both move and forward. The notion
> of giving up the object.
>
> *Just for illustration* lets call it give and *just for illustration*
> make it a function.
>
> The idea is simple - give expands to move in all cases *except* when
> called with forwarding reference, then it expands to forward.
>
> *That's it.*
>
> Then you give the object in all cases when you need to forward it to
> someone else
>
> void f(const String& s)
> {
> auto list = s.split();
>
> // use list
>
> memberfunc(give(list)); //< moves
> }
>
> template<class T>
> deltype(auto) func(T&& a)
> {
> return func_impl(give(a)); //< will forward - argument is "forwarding
> reference"
> }
>
> void func2(String&& a, auto&& b)
> {
> auto o = construct(give(b)); //< will forward
> o.call(give(a)); //< will move
>
> // Note the user can get these wrong; give will not!
> }
>
> You get the idea - give is smart enough to do the right thing.
>
>
> Of course this is not possible without compiler support, but is it *im*possible?
> I really doubt.
> The compiler should have all the information. And the only "new"
> information it *really* needs is
>
> __is_template_argment(decltype(arg))
>
> This is - to know the type is not part of the function original
> declaration, but substituted when the function was created on the call site.
>
There are several issues here.
1. So what happens if I just so happen to have a variable with the same
type as a template argument? This intrinsic is inherently fragile due to
asking the wrong question.
2. So what about template arguments that aren't deduced? Those would be
detected here as well. So again, this is the wrong question to ask.
The intrinsic you want is "__is_forwarding_reference(e)", where `e` is an
identifier expression that identifies a specific function parameter.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8d3b34de-c06a-4083-bb0c-8e2c7482abf0%40isocpp.org.
------=_Part_20393_465585470.1527428866728
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, May 27, 2018 at 7:22:13 AM UTC-4, mihailn...@gm=
ail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div><br></div><div>C++11 introduced amazing new core language features in=
the form of ownership semantics and perfect forwarding of argument, fixing=
fundamental limitations, previously present in the language.</div><div><br=
></div><div>Considering these features are now close to 10 years old I stro=
ngly believe they should be promoted to language level.</div><div><br></div=
><div>But there is more, I also believe the separation b/w the two is not n=
eeded <i>in practice.=C2=A0</i></div><div><i><br></i></div><div>And not onl=
y in practice, but there is also a common semantic core to both - they both=
implement the notion of <i>giving. </i></div></div></blockquote><div><br><=
/div><div>When you move an object into something else, there is a broad exp=
ectation that the object has been moved from once that expression completes=
.. This means you are free to reuse the old object, so long as you reset it =
to known state first. When you forward something, you <i>don't know</i>=
its current state. You don't know if it was moved from or not. You don=
't even know if it's OK for you to manipulate the object, because y=
ou don't know why you were <i>given</i> the kind of reference you were.=
</div><div><br></div><div>In forwarding cases, you were given something for=
one purpose: to <i>forward it</i>. In move cases, things are a lot less ab=
stract. Forwarding is something you do in a completely different context th=
an moving. The two constructs should not be combined.</div><div><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>This is v=
ery unique and strong relation, not to be ignored.</div><div>Yes, both impl=
ement the notion differently (pass-through vs transfer), but both are the a=
ction of giving up, saying goodbye to the object you have.</div><div><font =
face=3D"arial,sans-serif">After that you can not longer use it - you don=
9;t have it - unless you recreate it (reassign it).=C2=A0</font></div><div>=
<font face=3D"arial,sans-serif"><br></font></div><div><font face=3D"arial,s=
ans-serif">Lets get back to the practice. Because the action is final - you=
cant use both on one instance. You <i>either</i> <font face=3D"courier new=
,monospace">move</font> <i>or</i> <font face=3D"courier new,monospace">forw=
ard</font>.</font></div><div><font face=3D"arial,sans-serif"><br></font></d=
iv><div>When to use <font face=3D"courier new,monospace">move</font> and wh=
en <font face=3D"courier new,monospace">forward</font> is surprisingly non-=
trivial to learn, <i>especially</i>=C2=A0 considering no error will be repo=
rted in messing up either case.=C2=A0</div><div>This is VERY confusing to a=
beginner and even an experienced programmer can get confused - there are q=
uite a few stackoverflow questions "Is this a forwarding reference&quo=
t;, pointing to something with && on its type.</div><div><br></div>=
<div>Lastly, forward itself have massive problems of its own, from verbosit=
y, through confusing mandatory template param, to usability in extremely li=
mited context.</div><div><br></div><div><br></div><div><b>Universal Forward=
ing=C2=A0</b></div><div><b><br></b></div><div>Lest exploit the common base =
notion of both move and forward. The notion of giving up the object.=C2=A0<=
/div><div><i><br></i></div><div><i>Just for illustration</i> lets call it <=
font face=3D"courier new,monospace">give</font> and <i>just for illustratio=
n</i> make it a function.</div><div><br></div><div>The idea is simple - <fo=
nt face=3D"courier new,monospace">give</font> expands to <font face=3D"cour=
ier new,monospace">move</font> in all cases <i>except</i> when called with =
forwarding reference, then it expands to <font face=3D"courier new,monospac=
e">forward</font>.</div><div><br></div><div><b><i>That's it.</i></b></d=
iv><div><b></b><i></i><br></div><div>Then you <font face=3D"courier new,mon=
ospace">give</font><font face=3D"arial,sans-serif"> the object in all cases=
when you need to forward it to someone else</font></div><div><br></div><di=
v><font face=3D"courier new,monospace">void f(const String& s)</font></=
div><div><font face=3D"courier new,monospace">{</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 auto list =3D s.split();</font></div><div=
><font face=3D"courier new,monospace"><br></font></div><div><font face=3D"c=
ourier new,monospace">=C2=A0 // use list</font></div><div><font face=3D"cou=
rier new,monospace">=C2=A0=C2=A0</font></div><div><font face=3D"courier new=
,monospace">=C2=A0 memberfunc(give(list)); //< moves</font></div><div><f=
ont face=3D"courier new,monospace">}</font></div><div><font face=3D"courier=
new,monospace"><br></font></div><div><font face=3D"courier new,monospace">=
template<class T></font></div><div><font face=3D"courier new,monospac=
e">deltype(auto) func(T&& a)</font></div><div><font face=3D"courier=
new,monospace">{</font></div><div><font face=3D"courier new,monospace"><sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:courier new,monospace;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">=C2=A0return func_impl(give(a)); //< wil=
l forward - argument is "forwarding reference"</span><br></font><=
/div><div><font face=3D"courier new,monospace">}</font></div><div><font fac=
e=3D"courier new,monospace"><br></font></div><div><font face=3D"courier new=
,monospace"><div><font style=3D"border-bottom-color:rgb(34,34,34);border-bo=
ttom-style:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);bor=
der-left-style:none;border-left-width:0px;border-right-color:rgb(34,34,34);=
border-right-style:none;border-right-width:0px;border-top-color:rgb(34,34,3=
4);border-top-style:none;border-top-width:0px;margin-bottom:0px;margin-left=
:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;pa=
dding-right:0px;padding-top:0px" face=3D"courier new,monospace">void func2(=
String&& a, auto&& b)</font></div><div><font style=3D"borde=
r-bottom-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0=
px;border-left-color:rgb(34,34,34);border-left-style:none;border-left-width=
:0px;border-right-color:rgb(34,34,34);border-right-style:none;border-right-=
width:0px;border-top-color:rgb(34,34,34);border-top-style:none;border-top-w=
idth:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;=
padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px" face=
=3D"courier new,monospace">{</font></div><div><font style=3D"border-bottom-=
color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;border=
-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px;bord=
er-right-color:rgb(34,34,34);border-right-style:none;border-right-width:0px=
;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width:0px;=
margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;padding-b=
ottom:0px;padding-left:0px;padding-right:0px;padding-top:0px" face=3D"couri=
er new,monospace"><span style=3D"background-color:transparent;border-bottom=
-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;borde=
r-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px;bor=
der-right-color:rgb(34,34,34);border-right-style:none;border-right-width:0p=
x;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width:0px=
;color:rgb(34,34,34);display:inline;float:none;font-family:courier new,mono=
space;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;=
letter-spacing:normal;margin-bottom:0px;margin-left:0px;margin-right:0px;ma=
rgin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-=
top:0px;text-align:left;text-decoration:none;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px">=C2=A0 auto o =3D construct(give=
(b)); //< will forward=C2=A0</span></font></div><div style=3D"margin:0px=
;padding:0px;border:0px rgb(34,34,34);text-align:left;color:rgb(34,34,34);t=
ext-transform:none;text-indent:0px;letter-spacing:normal;font-size:13px;fon=
t-variant:normal;word-spacing:0px;white-space:normal;background-color:trans=
parent"><font style=3D"border-bottom-color:rgb(34,34,34);border-bottom-styl=
e:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-=
style:none;border-left-width:0px;border-right-color:rgb(34,34,34);border-ri=
ght-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);border=
-top-style:none;border-top-width:0px;margin-bottom:0px;margin-left:0px;marg=
in-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-rig=
ht:0px;padding-top:0px" face=3D"courier new,monospace"><span style=3D"backg=
round-color:transparent;border-bottom-color:rgb(34,34,34);border-bottom-sty=
le:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left=
-style:none;border-left-width:0px;border-right-color:rgb(34,34,34);border-r=
ight-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);borde=
r-top-style:none;border-top-width:0px;color:rgb(34,34,34);display:inline;fl=
oat:none;font-family:courier new,monospace;font-size:13px;font-style:normal=
;font-variant:normal;font-weight:400;letter-spacing:normal;margin-bottom:0p=
x;margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;paddin=
g-left:0px;padding-right:0px;padding-top:0px;text-align:left;text-decoratio=
n:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px">=C2=A0 o.call(give(a)); //< will move</span></font></div><div style=
=3D"margin:0px;padding:0px;border:0px rgb(34,34,34);text-align:left;color:r=
gb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font=
-size:13px;font-variant:normal;word-spacing:0px;white-space:normal;backgrou=
nd-color:transparent"><font style=3D"border-bottom-color:rgb(34,34,34);bord=
er-bottom-style:none;border-bottom-width:0px;border-left-color:rgb(34,34,34=
);border-left-style:none;border-left-width:0px;border-right-color:rgb(34,34=
,34);border-right-style:none;border-right-width:0px;border-top-color:rgb(34=
,34,34);border-top-style:none;border-top-width:0px;margin-bottom:0px;margin=
-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0=
px;padding-right:0px;padding-top:0px" face=3D"courier new,monospace"><b></b=
><i></i><u></u><sub></sub><sup></sup><strike></strike><br></font></div><div=
style=3D"margin:0px;padding:0px;border:0px rgb(34,34,34);text-align:left;c=
olor:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:norma=
l;font-size:13px;font-variant:normal;word-spacing:0px;white-space:normal;ba=
ckground-color:transparent"><font style=3D"border-bottom-color:rgb(34,34,34=
);border-bottom-style:none;border-bottom-width:0px;border-left-color:rgb(34=
,34,34);border-left-style:none;border-left-width:0px;border-right-color:rgb=
(34,34,34);border-right-style:none;border-right-width:0px;border-top-color:=
rgb(34,34,34);border-top-style:none;border-top-width:0px;margin-bottom:0px;=
margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-=
left:0px;padding-right:0px;padding-top:0px" face=3D"courier new,monospace">=
=C2=A0 // Note the user can get these wrong; give will not!</font><br></div=
></font><div><font face=3D"courier new,monospace"><font style=3D"border-bot=
tom-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;bo=
rder-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px;=
border-right-color:rgb(34,34,34);border-right-style:none;border-right-width=
:0px;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width:=
0px;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0px;paddi=
ng-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px" face=3D"c=
ourier new,monospace">}</font></font></div><div><font face=3D"courier new,m=
onospace"><br></font></div></div><div style=3D"text-align:left"><font face=
=3D"arial,sans-serif">You get the idea - <font face=3D"courier new,monospac=
e">give</font> is smart enough to do the right thing.</font></div><div styl=
e=3D"text-align:left"><font face=3D"arial,sans-serif"><br></font></div><b><=
/b><i></i><u></u><sub></sub><sup></sup><strike></strike><font face=3D"couri=
er new,monospace"></font><div><font face=3D"arial,sans-serif"></font><br></=
div><div>Of course this is not possible without compiler support, but is it=
<i>im</i>possible? I really doubt.</div><div>The compiler should have all =
the information. And the only "new" information it <i>really</i> =
needs is</div><div><br></div><div>__is_template_argment(<wbr>decltype(arg))=
</div><div><br></div><div>This is - to know the type is not part of the fun=
ction original declaration, but substituted when the function was created o=
n the call site.</div></div></blockquote><div><br></div><div>There are seve=
ral issues here.</div><div><br></div><div>1. So what happens if I just so h=
appen to have a variable with the same type as a template argument? This in=
trinsic is inherently fragile due to asking the wrong question.</div><div><=
br></div><div>2. So what about template arguments that aren't deduced? =
Those would be detected here as well. So again, this is the wrong question =
to ask.<br></div><br><div>The intrinsic you want is "__is_forwarding_r=
eference(e)", where `e` is an identifier expression that identifies a =
specific function parameter.<br></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8d3b34de-c06a-4083-bb0c-8e2c7482abf0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8d3b34de-c06a-4083-bb0c-8e2c7482abf0=
%40isocpp.org</a>.<br />
------=_Part_20393_465585470.1527428866728--
------=_Part_20392_518174215.1527428866727--
.
Author: mihailnajdenov@gmail.com
Date: Sun, 27 May 2018 09:22:04 -0700 (PDT)
Raw View
------=_Part_27041_447769957.1527438124642
Content-Type: multipart/alternative;
boundary="----=_Part_27042_342452661.1527438124642"
------=_Part_27042_342452661.1527438124642
Content-Type: text/plain; charset="UTF-8"
On Sunday, May 27, 2018 at 4:47:46 PM UTC+3, Nicol Bolas wrote:
>
> On Sunday, May 27, 2018 at 7:22:13 AM UTC-4, mihailn...@gmail.com wrote:
>>
>>
>> C++11 introduced amazing new core language features in the form of
>> ownership semantics and perfect forwarding of argument, fixing fundamental
>> limitations, previously present in the language.
>>
>> Considering these features are now close to 10 years old I strongly
>> believe they should be promoted to language level.
>>
>> But there is more, I also believe the separation b/w the two is not
>> needed *in practice. *
>>
>> And not only in practice, but there is also a common semantic core to
>> both - they both implement the notion of *giving. *
>>
>
> When you move an object into something else, there is a broad expectation
> that the object has been moved from once that expression completes. This
> means you are free to reuse the old object, so long as you reset it to
> known state first. When you forward something, you *don't know* its
> current state. You don't know if it was moved from or not. You don't even
> know if it's OK for you to manipulate the object, because you don't know
> why you were *given* the kind of reference you were.
>
> In forwarding cases, you were given something for one purpose: to *forward
> it*. In move cases, things are a lot less abstract. Forwarding is
> something you do in a completely different context than moving.
>
Nothing of what you just said changes when using give, simply because it
does not hide any information, it does not mask any parameter. All T&& are
just the same and as explicit as ever, same as all string&&-s.
The fact that the context is different, the fact the preconditions are
different does not change the outcome - object is gone, variable can only
be reassigned (in the case of rvalue ref, and again give does not hide the
argument and its type in any way, so if it is a frw ref is still clear) or
destroyed.
How you "get rid" of the variable changes nothing on the postconditions.
> The two constructs should not be combined.
>
Please name one instance when combined notion makes the code ambiguous,
unclear or misleading.
There aren't any, exactly because what you all said - the contexts are
vastly different!
It ALWAYS clear what to use.
It is AWALAYS wrong to use the other.
ALL information is available to the compiler
=> the compiler can do the work for us.
If you want to be explicit - the old functions will still be there, but I
am hard pressed to find ONE instance, where it is NEEDED.
Again, is there a place *ever* where this heuristic will be wrong?
And also is there a place *ever*, where the user have to comment
/*forwads!*/ or /*moves*/ to make it clear ?
> ...
>
> There are several issues here.
>
> 1. So what happens if I just so happen to have a variable with the same
> type as a template argument? This intrinsic is inherently fragile due to
> asking the wrong question.
>
> 2. So what about template arguments that aren't deduced? Those would be
> detected here as well. So again, this is the wrong question to ask.
>
> The intrinsic you want is "__is_forwarding_reference(e)", where `e` is an
> identifier expression that identifies a specific function parameter.
>
By all means it was just for an illustration. I don't propose exporting an intrinsic
simply because it will *not* help the user write a give operator/universal
forwarding.
Question is - is it possible? Is it possible for the compiler to expand
give to the correct expression, based on given context?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9930a9dc-b998-4431-a159-6d72d1d9b2ff%40isocpp.org.
------=_Part_27042_342452661.1527438124642
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, May 27, 2018 at 4:47:46 PM UTC+3, Nicol=
Bolas 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">=
On Sunday, May 27, 2018 at 7:22:13 AM UTC-4, <a>mihailn...@gmail.com</a> wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div=
><div>C++11 introduced amazing new core language features in the form of ow=
nership semantics and perfect forwarding of argument, fixing fundamental li=
mitations, previously present in the language.</div><div><br></div><div>Con=
sidering these features are now close to 10 years old I strongly believe th=
ey should be promoted to language level.</div><div><br></div><div>But there=
is more, I also believe the separation b/w the two is not needed <i>in pra=
ctice.=C2=A0</i></div><div><i><br></i></div><div>And not only in practice, =
but there is also a common semantic core to both - they both implement the =
notion of <i>giving. </i></div></div></blockquote><div><br></div><div>When =
you move an object into something else, there is a broad expectation that t=
he object has been moved from once that expression completes. This means yo=
u are free to reuse the old object, so long as you reset it to known state =
first. When you forward something, you <i>don't know</i> its current st=
ate. You don't know if it was moved from or not. You don't even kno=
w if it's OK for you to manipulate the object, because you don't kn=
ow why you were <i>given</i> the kind of reference you were.=C2=A0</div></d=
iv></blockquote><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"><div><br></div><div>In forwarding cases, you were given something for on=
e purpose: to <i>forward it</i>. In move cases, things are a lot less abstr=
act. Forwarding is something you do in a completely different context than =
moving. </div></div></blockquote><div><br></div><div><span style=3D"display=
: inline !important; float: none; background-color: transparent; color: rgb=
(34, 34, 34); font-family: "Arial","Helvetica",sans-ser=
if; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;">Nothing of what you just said=
changes when using give, simply because it does not hide any information, =
it does not mask any parameter. All T&& are just the same and as ex=
plicit as ever, same as all string&&-s.</span></div><div><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: "Arial","Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div>=
<div>The fact that the context is different, the fact the preconditions are=
different does not change the outcome - object is gone, variable can only =
be reassigned (in the case of rvalue ref, and again <font face=3D"courier n=
ew,monospace">give</font> does not hide the argument and its type in any wa=
y, so if it is a frw ref is still clear) or destroyed.</div><div><br></div>=
<div>How you "get rid" of the variable changes nothing on the pos=
tconditions.</div><div>=C2=A0</div><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"><div>The two constructs should not be combined.</div=
></div></blockquote><div><br></div><div>Please name one instance when combi=
ned notion makes the code ambiguous, unclear or misleading.</div><div><br><=
/div><div>There aren't any, exactly because what you all said - the con=
texts are vastly different!=C2=A0</div><div><br></div><div>It ALWAYS clear =
what to use.</div><div>It is AWALAYS wrong to use the other.</div><div>ALL =
information is available to the compiler</div><div><br></div><div>=3D> t=
he compiler can do the work for us.</div><div><br></div><div>If you want to=
be explicit - the old functions will still be there, but I am hard pressed=
to find ONE instance, where it is NEEDED.</div><div><br></div><div>Again, =
is there a place <i>ever</i> where this heuristic will be wrong?=C2=A0</div=
><div>And also is there a place <i>ever</i>, where the user have to comment=
/*forwads!*/ or /*moves*/ to make it clear ?<br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>...</div><d=
iv><br></div><div>There are several issues here.</div><div><br></div><div>1=
.. So what happens if I just so happen to have a variable with the same type=
as a template argument? This intrinsic is inherently fragile due to asking=
the wrong question.</div><div><br></div><div>2. So what about template arg=
uments that aren't deduced? Those would be detected here as well. So ag=
ain, this is the wrong question to ask.<br></div><br><div>The intrinsic you=
want is "__is_forwarding_reference(e)"<wbr>, where `e` is an ide=
ntifier expression that identifies a specific function parameter.<br></div>=
</div></blockquote><div><br></div><div>By all means it was just for an illu=
stration. I don't propose exporting an <span style=3D"display: inline !=
important; float: none; background-color: transparent; color: rgb(34, 34, 3=
4); font-family: "Arial","Helvetica",sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; orphans: 2; text-align: left; text-decoration: none; te=
xt-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white=
-space: normal; word-spacing: 0px;">intrinsic simply because it will <i>not=
</i> help the user write a give operator/universal forwarding.</span></div>=
<div><span style=3D"display: inline !important; float: none; background-col=
or: transparent; color: rgb(34, 34, 34); font-family: "Arial",&qu=
ot;Helvetica",sans-serif; font-size: 13px; font-style: normal; font-va=
riant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">Qu=
estion is - is it possible? Is it possible for the compiler to expand give =
to the correct expression, based on given context?</span></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9930a9dc-b998-4431-a159-6d72d1d9b2ff%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9930a9dc-b998-4431-a159-6d72d1d9b2ff=
%40isocpp.org</a>.<br />
------=_Part_27042_342452661.1527438124642--
------=_Part_27041_447769957.1527438124642--
.