Topic: Let's just make pointers to members invokable


Author: barry.revzin@gmail.com
Date: Tue, 2 Feb 2016 10:30:46 -0800 (PST)
Raw View
------=_Part_6883_154922440.1454437846818
Content-Type: multipart/alternative;
 boundary="----=_Part_6884_713984316.1454437846819"

------=_Part_6884_713984316.1454437846819
Content-Type: text/plain; charset=UTF-8

[func.require] brings up the aggressively shouty *INVOKE*(f, t1, t2, ...,
tN) with 5 special cases each to handle pointers-to-member-functions
(called on references or pointers) and pointers to member-data (called on
references or pointers) or normal free functions. This is complicated. We
also get *INVOKE*(f, t1, t2, ..., tN, R) to cast the result. We then get
[func.invoke] to provide a std::invoke() which does an *INVOKE*.
std::bind() and std::function<> handle all these separate subcases
internally in what I'm sure is a lot more lines of code than anybody wants
it to be. All of this to do what is really one of the simplest operations
we have: calling a member function.

How about we just simplify this and make pointers-to-member functions/data
actually themselves invokable? So given:

struct Foo {
   int bar(char );
};

Foo foo{...};
Foo *pfoo = &foo;
auto op = &Foo::bar;

We already have a few different ways of calling op on f with some char:

int a = (foo.*op)('a');
int b = (pfoo->*op)('b');
int c = std::invoke(op, foo, 'c');
int d = std::invoke(op, pfoo, 'd');
int e = std::bind(op, foo, 'e')();

Let's just add the most obvious one that we're missing:

int f = op(foo, 'f');
int g = op(pfoo, 'g');

This makes a function call actually look like a function call. It's clear
and unambiguous. And it would probably obviate the need for std::invoke()
too.

As a friendly extension, the next logical step would be to have these three
be equivalent:

auto op1 = [foo](auto&&... args){ return foo.bar(std::forward<decltype(args
)>(args)...); };
auto op2 = std::bind(&Foo::bar, foo, _all); // from N4171. More concise,
easier to remember, but doesn't support overloading names
auto op3 = foo.bar;

Because who really wants to ever type the first two, anyway?

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_6884_713984316.1454437846819
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">[func.require] brings up the aggressively shouty <i>INVOKE=
</i>(f, t1, t2, ..., tN) with 5 special cases each to handle pointers-to-me=
mber-functions (called on references or pointers) and pointers to member-da=
ta (called on references or pointers) or normal free functions. This is com=
plicated. We also get <i>INVOKE</i>(f, t1, t2, ..., tN, R) to cast the resu=
lt. We then get [func.invoke] to provide a std::invoke() which does an <i>I=
NVOKE</i>. std::bind() and std::function&lt;&gt; handle all these separate =
subcases internally in what I&#39;m sure is a lot more lines of code than a=
nybody wants it to be. All of this to do what is really one of the simplest=
 operations we have: calling a member function.<div><br></div><div>How abou=
t we just simplify this and make pointers-to-member functions/data actually=
 themselves invokable? So given:</div><div><br></div><div><div class=3D"pre=
ttyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo=
</span><font color=3D"#666600"><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> bar=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">char</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br></span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Foo</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{...};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">pfoo </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> op </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span></font></div></code></div><br>We already have a few diff=
erent ways of calling op on f with some char:</div><div><br></div><div><div=
 class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-=
wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><font color=3D"#000000"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> a </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>.*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">op</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&#39;a&#39;</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> <br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> b </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">pfoo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-&g=
t;*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">op</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&#39;b&#39;</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> c </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">invoke</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">op</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">&#39;c&#39;</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></font><font color=3D"#008800"><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> d </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">invoke</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">op</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> pfoo</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&#39;d&#39;</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> e </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">bind</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">op</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify">&#39;e&#39;</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)();</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span></font></div></code></div><br>Let&#39;s just add the most ob=
vious one that we&#39;re missing:</div><div><br></div><div><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> f </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> op</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #080;" class=3D"styled-by-prettify">&#39;f&#39;</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> g </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> op</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">pf=
oo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&#39;g&#39;</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">);</span></font></div></c=
ode></div><br>This makes a function call actually look like a function call=
.. It&#39;s clear and unambiguous. And it would probably obviate the need fo=
r std::invoke() too.</div><div><br></div><div>As a friendly extension, the =
next logical step would be to have these three be equivalent:<br></div><div=
><br></div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(1=
87, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> op1 </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
](</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;...<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> args</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">){</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">args</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)&gt;(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">args</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)...);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
op2 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">bind</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(&amp;</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> _all</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// from N4171. More concise,=
 easier to remember, but doesn&#39;t support overloading names</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> op3 </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br>Because who really wants to ever type the =
first two, anyway?=C2=A0</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_6884_713984316.1454437846819--
------=_Part_6883_154922440.1454437846818--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 2 Feb 2016 23:16:58 +0100
Raw View
This is a multi-part message in MIME format.
--------------060307070400060808040809
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 02/02/2016 19:30, barry.revzin@gmail.com a =C3=A9crit :
> [func.require] brings up the aggressively shouty /INVOKE/(f, t1, t2,=20
> ..., tN) with 5 special cases each to handle=20
> pointers-to-member-functions (called on references or pointers) and=20
> pointers to member-data (called on references or pointers) or normal=20
> free functions. This is complicated. We also get /INVOKE/(f, t1, t2,=20
> ..., tN, R) to cast the result. We then get [func.invoke] to provide a=20
> std::invoke() which does an /INVOKE/. std::bind() and std::function<>=20
> handle all these separate subcases internally in what I'm sure is a=20
> lot more lines of code than anybody wants it to be. All of this to do=20
> what is really one of the simplest operations we have: calling a=20
> member function.
>
> How about we just simplify this and make pointers-to-member=20
> functions/data actually themselves invokable? So given:
>
> |
> structFoo{
> intbar(char);
> };
>
> Foofoo{...};
> Foo*pfoo =3D&foo;
> autoop =3D&Foo::bar;
> |
>
> We already have a few different ways of calling op on f with some char:
>
> |
> inta =3D(foo.*op)('a');
> intb =3D(pfoo->*op)('b');
> intc =3Dstd::invoke(op,foo,'c');
> intd =3Dstd::invoke(op,pfoo,'d');
> inte =3Dstd::bind(op,foo,'e')();
> |
>
> Let's just add the most obvious one that we're missing:
>
> |
> intf =3Dop(foo,'f');
> intg =3Dop(pfoo,'g');
> |
>
> This makes a function call actually look like a function call. It's=20
> clear and unambiguous. And it would probably obviate the need for=20
> std::invoke() too.
>
> As a friendly extension, the next logical step would be to have these=20
> three be equivalent:
>
> |
> autoop1=20
> =3D[foo](auto&&...args){returnfoo.bar(std::forward<decltype(args)>(args).=
...);};
> autoop2 =3Dstd::bind(&Foo::bar,foo,_all);// from N4171. More concise,=20
> easier to remember, but doesn't support overloading names
> autoop3 =3Dfoo.bar;
> |
>
> Because who really wants to ever type the first two, anyway?
>
There's a related proposal P0119R0 - Overload sets as function arguments=20
[1]. It works for overloaded functions, but  it should be extensible to=20
your foo.bar member function.

Vicente

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0119r0.pdf

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--------------060307070400060808040809
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">Le 02/02/2016 19:30,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:barry.revzin@gma=
il.com">barry.revzin@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:84edf550-4d74-4ab9-9d1a-59aca568584b@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">[func.require] brings up the aggressively shouty <i>=
INVOKE</i>(f,
        t1, t2, ..., tN) with 5 special cases each to handle
        pointers-to-member-functions (called on references or pointers)
        and pointers to member-data (called on references or pointers)
        or normal free functions. This is complicated. We also get <i>INVOK=
E</i>(f,
        t1, t2, ..., tN, R) to cast the result. We then get
        [func.invoke] to provide a std::invoke() which does an <i>INVOKE</i=
>.
        std::bind() and std::function&lt;&gt; handle all these separate
        subcases internally in what I'm sure is a lot more lines of code
        than anybody wants it to be. All of this to do what is really
        one of the simplest operations we have: calling a member
        function.
        <div><br>
        </div>
        <div>How about we just simplify this and make pointers-to-member
          functions/data actually themselves invokable? So given:</div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">struct</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Foo</=
span><font
                  color=3D"#666600"><span style=3D"color: #000;"
                    class=3D"styled-by-prettify"> </span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                    =C2=A0 =C2=A0</span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">int</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> ba=
r</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">cha=
r</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">};</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                    <br>
                  </span><span style=3D"color: #606;"
                    class=3D"styled-by-prettify">Foo</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">{..=
..};</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #606;"
                    class=3D"styled-by-prettify">Foo</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">*</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">pfo=
o
                  </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">=3D</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">foo=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">auto</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> op
                  </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">=3D</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;</span><span
                    style=3D"color: #606;" class=3D"styled-by-prettify">Foo=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">bar=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span></font></div>
            </code></div>
          <br>
          We already have a few different ways of calling op on f with
          some char:</div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><font color=3D"#000000"><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> a =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">foo=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">.*<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">op<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">)(<=
/span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'a'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> <b=
r>
                  </span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">int</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> b =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">pfo=
o</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">-&g=
t;*</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">op<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">)(<=
/span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'b'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">int</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> c =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">inv=
oke</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">op<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'c'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span></font><font color=3D"#008800"><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> d =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">inv=
oke</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">op<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    pfoo</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'d'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">int</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> e =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">bin=
d</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">op<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'e'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">)()=
;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span></font></div>
            </code></div>
          <br>
          Let's just add the most obvious one that we're missing:</div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">int</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> f </=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><font
                  color=3D"#000000"><span style=3D"color: #000;"
                    class=3D"styled-by-prettify"> op</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">foo=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'f'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">int</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> g =
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> op=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">pfo=
o</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">'g'=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span></font></div>
            </code></div>
          <br>
          This makes a function call actually look like a function call.
          It's clear and unambiguous. And it would probably obviate the
          need for std::invoke() too.</div>
        <div><br>
        </div>
        <div>As a friendly extension, the next logical step would be to
          have these three be equivalent:<br>
        </div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); word-wrap: break-word; background-color: rgb(250,
            250, 250);"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">auto</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> op1 =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">[</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">foo</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">](</s=
pan><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
&amp;...</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> args=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">){</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">retur=
n</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> foo<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">bar</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">std</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">forwa=
rd</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">declt=
ype</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">args<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)&gt;=
(</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">args<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)...)=
;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">auto</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> op2 =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">bind<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(&amp=
;</span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Foo</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">bar</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> foo<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> _all=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #800;" class=3D"styled-by-prettify">//
                  from N4171. More concise, easier to remember, but
                  doesn't support overloading names</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">auto</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> op3 =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> foo<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">bar</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span></div>
            </code></div>
          <br>
          Because who really wants to ever type the first two, anyway?=C2=
=A0</div>
      </div>
      <br>
    </blockquote>
    There's a related proposal P0119R0 -
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    Overload sets as function arguments [1]. It works for overloaded
    functions, but=C2=A0 it should be extensible to your foo.bar member
    function.<br>
    <br>
    Vicente<br>
    <br>
    [1]
    <a class=3D"moz-txt-link-freetext" href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2015/p0119r0.pdf">http://www.open-std.org/jtc1/sc22/=
wg21/docs/papers/2015/p0119r0.pdf</a><br>
    <br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--------------060307070400060808040809--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 2 Feb 2016 15:18:11 -0800 (PST)
Raw View
------=_Part_2351_1920135811.1454455091758
Content-Type: multipart/alternative;
 boundary="----=_Part_2352_1453741352.1454455091759"

------=_Part_2352_1453741352.1454455091759
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 2, 2016 at 5:17:04 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 02/02/2016 19:30, barry....@gmail.com <javascript:> a =C3=A9crit :
>
> [func.require] brings up the aggressively shouty *INVOKE*(f, t1, t2, ...,=
=20
> tN) with 5 special cases each to handle pointers-to-member-functions=20
> (called on references or pointers) and pointers to member-data (called on=
=20
> references or pointers) or normal free functions. This is complicated. We=
=20
> also get *INVOKE*(f, t1, t2, ..., tN, R) to cast the result. We then get=
=20
> [func.invoke] to provide a std::invoke() which does an *INVOKE*.=20
> std::bind() and std::function<> handle all these separate subcases=20
> internally in what I'm sure is a lot more lines of code than anybody want=
s=20
> it to be. All of this to do what is really one of the simplest operations=
=20
> we have: calling a member function.=20
>
> How about we just simplify this and make pointers-to-member functions/dat=
a=20
> actually themselves invokable? So given:
>
> struct Foo {
>    int bar(char );
> };
>
> Foo foo{...};
> Foo *pfoo =3D &foo;
> auto op =3D &Foo::bar;
>
> We already have a few different ways of calling op on f with some char:
>
> int a =3D (foo.*op)('a');=20
> int b =3D (pfoo->*op)('b');
> int c =3D std::invoke(op, foo, 'c');
> int d =3D std::invoke(op, pfoo, 'd');
> int e =3D std::bind(op, foo, 'e')();
>
> Let's just add the most obvious one that we're missing:
>
> int f =3D op(foo, 'f');
> int g =3D op(pfoo, 'g');
>
> This makes a function call actually look like a function call. It's clear=
=20
> and unambiguous. And it would probably obviate the need for std::invoke()=
=20
> too.
>
> As a friendly extension, the next logical step would be to have these=20
> three be equivalent:
>
> auto op1 =3D [foo](auto&&... args){ return foo.bar(std::forward<decltype(
> args)>(args)...); };
> auto op2 =3D std::bind(&Foo::bar, foo, _all); // from N4171. More concise=
,=20
> easier to remember, but doesn't support overloading names
> auto op3 =3D foo.bar;
>
> Because who really wants to ever type the first two, anyway?=20
>
> There's a related proposal P0119R0 - Overload sets as function arguments=
=20
> [1]. It works for overloaded functions, but  it should be extensible to=
=20
> your foo.bar member function.
>
> Vicente
>
> [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0119r0.pdf
>

It should be noted that P0119 is a refinement (of sorts) of N3617=20
<http://wg21.link/N3617>, where said functionality was available.

Personally, I would say that P0119 is *woefully incomplete* without the=20
ability to use it on member functions. I'm not big on having it capture a=
=20
particular `this`, but the use of lambda syntax in N3617makes that both=20
possible and consistent across other lambda syntax.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_2352_1453741352.1454455091759
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 2, 2016 at 5:17:04 PM UTC-5, Vicente =
J. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Le 02/02/2016 19:30,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"E7=
Wub-QRHAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>barry....@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">[func.require] brings up the aggressively shouty <i>=
INVOKE</i>(f,
        t1, t2, ..., tN) with 5 special cases each to handle
        pointers-to-member-functions (called on references or pointers)
        and pointers to member-data (called on references or pointers)
        or normal free functions. This is complicated. We also get <i>INVOK=
E</i>(f,
        t1, t2, ..., tN, R) to cast the result. We then get
        [func.invoke] to provide a std::invoke() which does an <i>INVOKE</i=
>.
        std::bind() and std::function&lt;&gt; handle all these separate
        subcases internally in what I&#39;m sure is a lot more lines of cod=
e
        than anybody wants it to be. All of this to do what is really
        one of the simplest operations we have: calling a member
        function.
        <div><br>
        </div>
        <div>How about we just simplify this and make pointers-to-member
          functions/data actually themselves invokable? So given:</div>
        <div><br>
        </div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">struct</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#606">Foo</span><font color=3D"#666=
600"><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000"><br>
                    =C2=A0 =C2=A0</span><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#008">char</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"><br>
                  </span><span style=3D"color:#660">};</span><span style=3D=
"color:#000"><br>
                    <br>
                  </span><span style=3D"color:#606">Foo</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">{...};</span><span st=
yle=3D"color:#000"><br>
                  </span><span style=3D"color:#606">Foo</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">*</span><span style=3D"c=
olor:#000">pfoo
                  </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><span style=
=3D"color:#000">foo</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>
                  </span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> op
                  </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><span style=
=3D"color:#606">Foo</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">bar</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>
                  </span></font></div>
            </code></div>
          <br>
          We already have a few different ways of calling op on f with
          some char:</div>
        <div><br>
        </div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><font color=3D"#000000"><span style=3D"color:#008">int</=
span><span style=3D"color:#000"> a </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">foo</span><span style=3D"color:#660">.*</span><sp=
an style=3D"color:#000">op</span><span style=3D"color:#660">)(</span><span =
style=3D"color:#080">&#39;a&#39;</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"> <br>
                  </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">pfoo</span><span style=3D"color:#660">-&gt;*</span><span style=
=3D"color:#000">op</span><span style=3D"color:#660">)(</span><span style=3D=
"color:#080">&#39;b&#39;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
                  </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> c </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">invoke</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">op</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> foo</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#080">&#39;c&#39;</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br>
                  </span></font><font color=3D"#008800"><span style=3D"colo=
r:#008">int</span><span style=3D"color:#000"> d </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">invoke</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">op</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000">
                    pfoo</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#080">&#39;d&#39;</span><spa=
n style=3D"color:#660">);</span><span style=3D"color:#000"><br>
                  </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> e </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">bind</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">op</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> foo</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#080">&#39;e&#39;</span><span style=
=3D"color:#660">)();</span><span style=3D"color:#000"><br>
                  </span></font></div>
            </code></div>
          <br>
          Let&#39;s just add the most obvious one that we&#39;re missing:</=
div>
        <div><br>
        </div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">int</span><span style=3D"colo=
r:#000"> f </span><span style=3D"color:#660">=3D</span><font color=3D"#0000=
00"><span style=3D"color:#000"> op</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">foo</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#080">&#39;f&#39;</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>
                  </span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> g </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> op</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">pfoo</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&#39;g&#39;</span><span style=
=3D"color:#660">);</span></font></div>
            </code></div>
          <br>
          This makes a function call actually look like a function call.
          It&#39;s clear and unambiguous. And it would probably obviate the
          need for std::invoke() too.</div>
        <div><br>
        </div>
        <div>As a friendly extension, the next logical step would be to
          have these three be equivalent:<br>
        </div>
        <div><br>
        </div>
        <div>
          <div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-w=
ord;background-color:rgb(250,250,250)"><code>
              <div><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> op1 </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">[</span><span style=3D"color:#=
000">foo</span><span style=3D"color:#660">](</span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#660">&amp;&amp;...</span><span style=3D=
"color:#000"> args</span><span style=3D"color:#660">){</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">return</span><span style=3D=
"color:#000"> foo</span><span style=3D"color:#660">.</span><span style=3D"c=
olor:#000">bar</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#000">std</span><span style=3D"color:#660">::</span><span style=3D"color:=
#000">forward</span><span style=3D"color:#660">&lt;</span><span style=3D"co=
lor:#008">decltype</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000"><wbr>args</span><span style=3D"color:#660">)&gt;(</span><span s=
tyle=3D"color:#000">args</span><span style=3D"color:#660">)...);</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">};</span><span st=
yle=3D"color:#000"><br>
                </span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> op2 </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">bind</span><span style=3D"color:#660">(&amp;</span><span st=
yle=3D"color:#606">Foo</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">bar</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> _all</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"> </span><span style=3D"color:#800">//
                  from N4171. More concise, easier to remember, but
                  doesn&#39;t support overloading names</span><span style=
=3D"color:#000"><br>
                </span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> op3 </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">.</span><span style=
=3D"color:#000">bar</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>
                </span></div>
            </code></div>
          <br>
          Because who really wants to ever type the first two, anyway?=C2=
=A0</div>
      </div>
      <br>
    </blockquote>
    There&#39;s a related proposal P0119R0 -
   =20
    Overload sets as function arguments [1]. It works for overloaded
    functions, but=C2=A0 it should be extensible to your foo.bar member
    function.<br>
    <br>
    Vicente<br>
    <br>
    [1]
    <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p011=
9r0.pdf" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39=
;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%=
2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0119r0.pdf\46sa\75D\46sntz\0751\46usg\75AF=
QjCNG-3lvQeHULEsBQEZdt2upGAVe5Kw&#39;;return true;" onclick=3D"this.href=3D=
&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fs=
c22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0119r0.pdf\46sa\75D\46sntz\0751\46usg\=
75AFQjCNG-3lvQeHULEsBQEZdt2upGAVe5Kw&#39;;return true;">http://www.open-std=
..org/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>p0119r0.pdf</a><br></div></b=
lockquote><div><br>It should be noted that P0119 is a refinement (of sorts)=
 of <a href=3D"http://wg21.link/N3617">N3617</a>, where said functionality =
was available.<br><br>Personally, I would say that P0119 is <i>woefully inc=
omplete</i> without the ability to use it on member functions. I&#39;m not =
big on having it capture a particular `this`, but the use of lambda syntax =
in N3617makes that both possible and consistent across other lambda syntax.=
<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_2352_1453741352.1454455091759--
------=_Part_2351_1920135811.1454455091758--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 2 Feb 2016 16:27:00 -0800 (PST)
Raw View
------=_Part_12_1976022728.1454459220605
Content-Type: multipart/alternative;
 boundary="----=_Part_13_458303295.1454459220607"

------=_Part_13_458303295.1454459220607
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 2, 2016 at 10:30:47 AM UTC-8, barry....@gmail.com=20
wrote:
>
> [func.require] brings up the aggressively shouty *INVOKE*(f, t1, t2, ...,=
=20
> tN) with 5 special cases each to handle pointers-to-member-functions=20
> (called on references or pointers) and pointers to member-data (called on=
=20
> references or pointers) or normal free functions. This is complicated. We=
=20
> also get *INVOKE*(f, t1, t2, ..., tN, R) to cast the result. We then get=
=20
> [func.invoke] to provide a std::invoke() which does an *INVOKE*.=20
> std::bind() and std::function<> handle all these separate subcases=20
> internally in what I'm sure is a lot more lines of code than anybody want=
s=20
> it to be. All of this to do what is really one of the simplest operations=
=20
> we have: calling a member function.
>
> How about we just simplify this and make pointers-to-member functions/dat=
a=20
> actually themselves invokable? So given:
>
> struct Foo {
>    int bar(char );
> };
>
> Foo foo{...};
> Foo *pfoo =3D &foo;
> auto op =3D &Foo::bar;
>
> We already have a few different ways of calling op on f with some char:
>
> int a =3D (foo.*op)('a');=20
> int b =3D (pfoo->*op)('b');
> int c =3D std::invoke(op, foo, 'c');
> int d =3D std::invoke(op, pfoo, 'd');
> int e =3D std::bind(op, foo, 'e')();
>
> Let's just add the most obvious one that we're missing:
>
> int f =3D op(foo, 'f');
> int g =3D op(pfoo, 'g');
>

This makes sense to me.
My kneejerk reaction was "you can't do that, because it would affect=20
SFINAE"; but then I thought some more, and I think that it's pretty likely=
=20
that it would only affect SFINAE in the intended way. For example, let's=20
take a new pet cause of mine:

template<class M>
auto operator<< (std::ostream& os, const M& m) -> decltype(m(os))
{
    return m(os);
}

This lets me write things like

template<class T>
 auto commaize(const T& t)
 {
     return [&t](std::ostream& os) -> std::ostream& {
         return os << t << ", ";
     };
 }
// ...
std::cout << commaize("hello") << commaize("love") << std::endl;

Under your proposal's effect on SFINAE, it would also let me write

std::cout << &basic_ostream::flush;

as a synonym for

std::cout.flush();

This... doesn't seem at all bad, actually!  I'm okay with this. :)

This proposal will conflict with the broader "unified function call syntax"=
=20
proposal; but in a benign and friendly way. It's kind of "UFCS Lite".


As a friendly extension, the next logical step would be to have these three=
=20
> be equivalent:
>
> auto op1 =3D [foo](auto&&... args){ return foo.bar(std::forward<decltype(
> args)>(args)...); };
> auto op2 =3D std::bind(&Foo::bar, foo, _all); // from N4171. More concise=
,=20
> easier to remember, but doesn't support overloading names
> auto op3 =3D foo.bar;
>
> Because who really wants to ever type the first two, anyway?
>

Agreed that the first two are ugly, but the third seems semantically=20
confusing. Is it equivalent to the first (op1), in that it makes a copy of=
=20
foo?
If I wanted to capture foo "by reference", could I write auto op4 =3D=20
(&foo)->bar; ?  There's also going to be conflicts here with the=20
proposal(s?) regarding "operator dot".

And aren't there horrible issues here with virtual functions?
For example, consider

struct Base { virtual void bar(); }
struct Derived : Base { void bar() override; }

void frotz(Base *p)
{
    auto op5 =3D [x =3D *p](auto&&... args){ return x.bar(std::forward<decl=
type(
args)>(args)...); }
    auto op6 =3D (*p).bar;
    op5();  // calls Base::bar() on a sliced copy of *p, regardless of *p's=
=20
dynamic type
    op6();  // ditto?
}

In the above example, is op6 really going to be a synonym for op5? and if=
=20
so, *YUCK.*

my $.02,
=E2=80=93Arthur

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_13_458303295.1454459220607
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 2, 2016 at 10:30:47 AM UTC-8, barry..=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">[func.require] brings up the aggressively shouty <i>INVOKE</i>(f, t1,=
 t2, ..., tN) with 5 special cases each to handle pointers-to-member-functi=
ons (called on references or pointers) and pointers to member-data (called =
on references or pointers) or normal free functions. This is complicated. W=
e also get <i>INVOKE</i>(f, t1, t2, ..., tN, R) to cast the result. We then=
 get [func.invoke] to provide a std::invoke() which does an <i>INVOKE</i>. =
std::bind() and std::function&lt;&gt; handle all these separate subcases in=
ternally in what I&#39;m sure is a lot more lines of code than anybody want=
s it to be. All of this to do what is really one of the simplest operations=
 we have: calling a member function.<div><br></div><div>How about we just s=
implify this and make pointers-to-member functions/data actually themselves=
 invokable? So given:</div><div><br></div><div><div style=3D"border:1px sol=
id rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"=
><code><div><span style=3D"color:#008">struct</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Foo</span><font color=3D"#666600"><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"><br>=C2=A0 =C2=A0</span><span style=3D"color:#008">int<=
/span><span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#008">char</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">);</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><br></s=
pan><span style=3D"color:#606">Foo</span><span style=3D"color:#000"> foo</s=
pan><span style=3D"color:#660">{...};</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#606">Foo</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">*</span><span style=3D"color:#000">pfoo </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&amp;</span><span style=3D"color:#000">foo</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">auto</span><span style=3D"color:#000"> op </span>=
<span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">&amp;</span><span style=3D"color:#606">Foo</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">bar</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></font=
></div></code></div><br>We already have a few different ways of calling op =
on f with some char:</div><div><br></div><div><div style=3D"border:1px soli=
d rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)">=
<code><div><font color=3D"#000000"><span style=3D"color:#008">int</span><sp=
an style=3D"color:#000"> a </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">foo</span><span style=3D"color:#660">.*</span><span style=
=3D"color:#000">op</span><span style=3D"color:#660">)(</span><span style=3D=
"color:#080">&#39;a&#39;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"> <br></span><span style=3D"color:#008">int</span><span s=
tyle=3D"color:#000"> b </span><span style=3D"color:#660">=3D</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">pfoo</span><span style=3D"color:#660">-&gt;*</span><span st=
yle=3D"color:#000">op</span><span style=3D"color:#660">)(</span><span style=
=3D"color:#080">&#39;b&#39;</span><span style=3D"color:#660">);</span><span=
 style=3D"color:#000"><br></span><span style=3D"color:#008">int</span><span=
 style=3D"color:#000"> c </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">invoke</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">op</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#080">&#39;c&#39;</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"><br></span></font>=
<font color=3D"#008800"><span style=3D"color:#008">int</span><span style=3D=
"color:#000"> d </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#000">invoke</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">op</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> pfoo</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#080">&#39;d&#39;</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#008">int</span><span style=3D"color:#000"> e </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">bind</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">op</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&#3=
9;e&#39;</span><span style=3D"color:#660">)();</span><span style=3D"color:#=
000"><br></span></font></div></code></div><br>Let&#39;s just add the most o=
bvious one that we&#39;re missing:</div><div><br></div><div><div style=3D"b=
order:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(=
250,250,250)"><code><div><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> f </span><span style=3D"color:#660">=3D</span><font color=
=3D"#000000"><span style=3D"color:#000"> op</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">foo</span><span style=3D"color:#660">,=
</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&#39;f=
&#39;</span><span style=3D"color:#660">);</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">int</span><span style=3D"color:#000">=
 g </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
op</span><span style=3D"color:#660">(</span><span style=3D"color:#000">pfoo=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#080">&#39;g&#39;</span><span style=3D"color:#660">)=
;</span></font></div></code></div></div></div></blockquote><div><br></div><=
div>This makes sense to me.</div><div>My kneejerk reaction was &quot;you ca=
n&#39;t do that, because it would affect SFINAE&quot;; but then I thought s=
ome more, and I think that it&#39;s pretty likely that it would only affect=
 SFINAE in the intended way. For example, let&#39;s take a new pet cause of=
 mine:</div><br><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> M</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ope=
rator</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">ostream</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> os</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> M<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> m</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">m</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">os</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> m</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">os</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span></div></code></div><div><div><br><div>This lets me write things like=
</div><div><br></div></div><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> commaize</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> t<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">[&amp;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">](</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">ostream</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> os</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">ostream</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> os </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> t </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">&quot;, &quot;</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// ...<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> commaize</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&quot;hello&quot;</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> commaize</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&quot;love&quot;</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">endl</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></=
code></div><div><br></div><div>Under your proposal&#39;s effect on SFINAE, =
it would also let me write</div><div><br></div><div class=3D"prettyprint" s=
tyle=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 18=
7, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">basic_ostream</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">flush</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></div></code></div><div><div><br></div><div>a=
s a synonym for</div><div><br></div><div class=3D"prettyprint" style=3D"bac=
kground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">cout</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">flush</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span></div></code></div><div><br></div><div>This=
.... doesn&#39;t seem at all bad, actually! =C2=A0I&#39;m okay with this. :)=
</div><div><br></div><div>This proposal will conflict with the broader &quo=
t;unified function call syntax&quot; proposal; but in a benign and friendly=
 way. It&#39;s kind of &quot;UFCS Lite&quot;.</div><div><br></div><div><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>As=
 a friendly extension, the next logical step would be to have these three b=
e equivalent:<br></div><div><br></div><div><div style=3D"border:1px solid r=
gb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><co=
de><div><span style=3D"color:#008">auto</span><span style=3D"color:#000"> o=
p1 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">[</span><span style=3D"color:#000">foo</s=
pan><span style=3D"color:#660">](</span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000=
"> args</span><span style=3D"color:#660">){</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">return</span><span style=3D"color:#000=
"> foo</span><span style=3D"color:#660">.</span><span style=3D"color:#000">=
bar</span><span style=3D"color:#660">(</span><span style=3D"color:#000">std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">forwa=
rd</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">d=
ecltype</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
><wbr>args</span><span style=3D"color:#660">)&gt;(</span><span style=3D"col=
or:#000">args</span><span style=3D"color:#660">)...);</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">};</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> op2 </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">bind</span><span style=3D"color:#660">(&amp;</span><span style=3D"=
color:#606">Foo</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">bar</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> foo</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> _all</span><span style=3D"color:#660">);</span><span style=3D"color:#=
000"> </span><span style=3D"color:#800">// from N4171. More concise, easier=
 to remember, but doesn&#39;t support overloading names</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> op3 </span><span style=3D"color:#660">=3D</span><span sty=
le=3D"color:#000"> foo</span><span style=3D"color:#660">.</span><span style=
=3D"color:#000">bar</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br></span></div></code></div><br>Because who really wants to =
ever type the first two, anyway?</div></div></blockquote><div><br></div><di=
v>Agreed that the first two are ugly, but the third seems semantically conf=
using. Is it equivalent to the first (op1), in that it makes a copy of foo?=
</div><div>If I wanted to capture foo &quot;by reference&quot;, could I wri=
te <font face=3D"courier new, monospace">auto op4 =3D (&amp;foo)-&gt;bar;</=
font> ? =C2=A0There&#39;s also going to be conflicts here with the proposal=
(s?) regarding &quot;operator dot&quot;.</div><div><br></div><div>And aren&=
#39;t there horrible issues here with virtual functions?</div><div>For exam=
ple, consider<br></div><div><br></div><div></div></div></div><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px sol=
id rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint">=
<div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
Base</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">virtual</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> bar</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Derived</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Base</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">override</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f=
rotz</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">p</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> op5 </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">x </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">p</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">](</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;&amp;...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">){</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">bar</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
forward</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">decltype<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">args</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)&gt;(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">args</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)...);</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> op6 </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">p</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">).</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">bar</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 op5</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color:=
 #800;" class=3D"styled-by-prettify">// calls Base::bar() on a sliced copy =
of *p, regardless of *p&#39;s dynamic type</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 op6</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// ditto?</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span></div></code></div><div><br></div><div>In=
 the above example, is op6 really going to be a synonym for op5? and if so,=
 <i><b>YUCK.</b></i></div><div><br></div><div>my $.02,</div><div>=E2=80=93A=
rthur</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_13_458303295.1454459220607--
------=_Part_12_1976022728.1454459220605--

.


Author: "T. C." <rs2740@gmail.com>
Date: Wed, 3 Feb 2016 01:24:49 -0800 (PST)
Raw View
------=_Part_60_320456201.1454491490071
Content-Type: multipart/alternative;
 boundary="----=_Part_61_1614909402.1454491490071"

------=_Part_61_1614909402.1454491490071
Content-Type: text/plain; charset=UTF-8

INVOKE supports reference_wrappers and (arbitrary) smart pointers. Do we
want this hypothetical pmf(object, args...) syntax to support them too?

On Tuesday, February 2, 2016 at 7:27:00 PM UTC-5, Arthur O'Dwyer wrote:
>
>
> My kneejerk reaction was "you can't do that, because it would affect
> SFINAE"; but then I thought some more, and I think that it's pretty likely
> that it would only affect SFINAE in the intended way.
>

That's also my first reaction, but I'm not as optimistic. I suspect that
this will create ambiguities when there previously was none.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_61_1614909402.1454491490071
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">INVOKE supports reference_wrappers and (arbitrary) smart p=
ointers. Do we want this hypothetical pmf(object, args...) syntax to suppor=
t them too? =C2=A0<div><div><br>On Tuesday, February 2, 2016 at 7:27:00 PM =
UTC-5, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div dir=3D"ltr"><br><div>My kneejerk reaction was &quot;you can&#39;t do=
 that, because it would affect SFINAE&quot;; but then I thought some more, =
and I think that it&#39;s pretty likely that it would only affect SFINAE in=
 the intended way. </div></div></blockquote><div><br></div><div>That&#39;s =
also my first reaction, but I&#39;m not as optimistic. I suspect that this =
will create ambiguities when there previously was none.</div><div>=C2=A0</d=
iv></div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_61_1614909402.1454491490071--
------=_Part_60_320456201.1454491490071--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 03 Feb 2016 11:31:52 -0500
Raw View
On 2016-02-02 13:30, barry.revzin@gmail.com wrote:
> How about we just simplify this and make pointers-to-member functions/data
> actually themselves invokable? So given:
>
> struct Foo {
>    int bar(char );
> };
>
> Foo foo{...};
> Foo *pfoo = &foo;
> auto op = &Foo::bar;
>
> We already have a few different ways of calling op on f with some char:
>
> int a = (foo.*op)('a');
> int b = (pfoo->*op)('b');
> int c = std::invoke(op, foo, 'c');
> int d = std::invoke(op, pfoo, 'd');
> int e = std::bind(op, foo, 'e')();
>
> Let's just add the most obvious one that we're missing:
>
> int f = op(foo, 'f');
> int g = op(pfoo, 'g');

Uh, no... this would require two features, one of which I expect will
meet heavy resistance. I think you meant e.g.:

  (*op)(foo, 'f');

And with unified call syntax, there's actually a decent motivation why
this ought to Just Work... because *this does work*:

  bar(foo, 'f'); // calls foo.bar('f')!

> This makes a function call actually look like a function call. It's clear
> and unambiguous.

It makes a function pointer dereference happen magically. Per above, I
hope you didn't mean that.

I like the idea of making ptmf calls work like ptff calls. I don't like
the idea of making function pointers act like functions.

> As a friendly extension, the next logical step would be to have these three
> be equivalent:
>
> auto op3 = foo.bar;

This might be a harder sell; there's a lot more magic happening there.
(OTOH, you can do that in Python...)

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 03 Feb 2016 11:36:20 -0500
Raw View
On 2016-02-03 04:24, T. C. wrote:
> INVOKE supports reference_wrappers and (arbitrary) smart pointers. Do we
> want this hypothetical pmf(object, args...) syntax to support them too?

The "easy" way of doing this is to simply define that, for a PTMF `pf`:

  (*pf)(x, ...);

....is syntactically equivalent to:

  ((x).(*pf))(...);

IOW, `x` must be a reference to class type (or implicitly convertible to
such), which may mean that `x` is actually `*p` or something.

--
Matthew

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 03 Feb 2016 11:49:42 -0500
Raw View
> I like the idea of making ptmf calls work like ptff calls. I don't like
the idea of making function pointers act like functions.

Um...

void f();
....
void (*pf)() =3D f;
=C2=A0=E2=80=8Epf(); // deref not needed

This already works.=C2=A0

Or did I misunderstand what you are saying?

Tony
P.S.=E2=80=8E I like the direction of the idea of this proposal.

Sent=C2=A0from=C2=A0my=C2=A0BlackBerry=C2=A0portable=C2=A0Babbage=C2=A0Devi=
ce
=C2=A0 Original Message =C2=A0
From: Matthew Woehlke
Sent: Wednesday, February 3, 2016 11:32 AM
To: std-proposals@isocpp.org
Reply To: std-proposals@isocpp.org
Subject: [std-proposals] Re: Let's just make pointers to members invokable

On 2016-02-02 13:30, barry.revzin@gmail.com wrote:
> How about we just simplify this and make pointers-to-member functions/dat=
a=20
> actually themselves invokable? So given:
>=20
> struct Foo {
> int bar(char );
> };
>=20
> Foo foo{...};
> Foo *pfoo =3D &foo;
> auto op =3D &Foo::bar;
>=20
> We already have a few different ways of calling op on f with some char:
>=20
> int a =3D (foo.*op)('a');=20
> int b =3D (pfoo->*op)('b');
> int c =3D std::invoke(op, foo, 'c');
> int d =3D std::invoke(op, pfoo, 'd');
> int e =3D std::bind(op, foo, 'e')();
>=20
> Let's just add the most obvious one that we're missing:
>=20
> int f =3D op(foo, 'f');
> int g =3D op(pfoo, 'g');

Uh, no... this would require two features, one of which I expect will
meet heavy resistance. I think you meant e.g.:

(*op)(foo, 'f');

And with unified call syntax, there's actually a decent motivation why
this ought to Just Work... because *this does work*:

bar(foo, 'f'); // calls foo.bar('f')!

> This makes a function call actually look like a function call. It's clear=
=20
> and unambiguous.

It makes a function pointer dereference happen magically. Per above, I
hope you didn't mean that.

I like the idea of making ptmf calls work like ptff calls. I don't like
the idea of making function pointers act like functions.

> As a friendly extension, the next logical step would be to have these thr=
ee=20
> be equivalent:
>=20
> auto op3 =3D foo.bar;

This might be a harder sell; there's a lot more magic happening there.
(OTOH, you can do that in Python...)

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 03 Feb 2016 12:03:46 -0500
Raw View
On 2016-02-03 11:49, Tony V E wrote:
>> I like the idea of making ptmf calls work like ptff calls. I don't like
>> the idea of making function pointers act like functions.
>=20
> Um...
>=20
> void f();
> ...
> void (*pf)() =3D f;
>  =E2=80=8Epf(); // deref not needed
>=20
> This already works.=20

Huh. Apparently I've never done that :-). (TBH I'm not sure I *like* it,
either...)

That makes it strange that you can't do anything similar with PTMF's,
but of course there is more room for ambiguity there.

Anyway, that being the case, I withdraw the objection, although I'd hope
that my syntax would also work.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 03 Feb 2016 13:56:03 -0500
Raw View
Yes, the lack of deref bothered me for a few years as well - deref is a goo=
d sign of "should I check for null?" =E2=80=8Eand the deref _should_ be req=
uired by the type system, and it just seems like a hack that it isn't requi=
red.=C2=A0

But eventually I got over it.

Sent=C2=A0from=C2=A0my=C2=A0BlackBerry=C2=A0portable=C2=A0Babbage=C2=A0Devi=
ce
=C2=A0 Original Message =C2=A0
From: Matthew Woehlke
Sent: Wednesday, February 3, 2016 12:03 PM
To: std-proposals@isocpp.org
Reply To: std-proposals@isocpp.org
Subject: [std-proposals] Re: Let's just make pointers to members invokable

On 2016-02-03 11:49, Tony V E wrote:
>> I like the idea of making ptmf calls work like ptff calls. I don't like
>> the idea of making function pointers act like functions.
>=20
> Um...
>=20
> void f();
> ...
> void (*pf)() =3D f;
> =E2=80=8Epf(); // deref not needed
>=20
> This already works.=20

Huh. Apparently I've never done that :-). (TBH I'm not sure I *like* it,
either...)

That makes it strange that you can't do anything similar with PTMF's,
but of course there is more room for ambiguity there.

Anyway, that being the case, I withdraw the objection, although I'd hope
that my syntax would also work.

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

.


Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Thu, 4 Feb 2016 05:53:18 -0800 (PST)
Raw View
------=_Part_519_1985893359.1454593998428
Content-Type: multipart/alternative;
 boundary="----=_Part_520_838473568.1454593998428"

------=_Part_520_838473568.1454593998428
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, February 3, 2016 at 5:03:57 PM UTC, Matthew Woehlke wrote:
>
> On 2016-02-03 11:49, Tony V E wrote:=20
> >> I like the idea of making ptmf calls work like ptff calls. I don't lik=
e=20
> >> the idea of making function pointers act like functions.=20
> >=20
> > Um...=20
> >=20
> > void f();=20
> > ...=20
> > void (*pf)() =3D f;=20
> >  =E2=80=8Epf(); // deref not needed=20
> >=20
> > This already works.=20
>

> Huh. Apparently I've never done that :-). (TBH I'm not sure I *like* it,=
=20
> either...)=20
>
>
This comes straight from traditional C and has been like this forever. Also=
=20
note that function names decay implicitly to function pointers without=20
requiring the application of operator&. That's not the case with PMFs,=20
which were added in C++. So if PMFs required explicit dereference to be=20
called it would actually be consistent.=20

I do not have a preference myself, just wanted to expand on the topic.

-- gpd

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_520_838473568.1454593998428
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, February 3, 2016 at 5:03:57 PM UTC, Matthew =
Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-02-03 11=
:49, Tony V E wrote:
<br>&gt;&gt; I like the idea of making ptmf calls work like ptff calls. I d=
on&#39;t like
<br>&gt;&gt; the idea of making function pointers act like functions.
<br>&gt;=20
<br>&gt; Um...
<br>&gt;=20
<br>&gt; void f();
<br>&gt; ...
<br>&gt; void (*pf)() =3D f;
<br>&gt; =C2=A0=E2=80=8Epf(); // deref not needed
<br>&gt;=20
<br>&gt; This already works.=20
<br></blockquote><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>Huh. Apparently I&#39;ve never done that :-). (TBH I&#39;m not sure I *=
like* it,
<br>either...)
<br>
<br></blockquote><div><br>This comes straight from traditional C and has be=
en like this forever. Also note that function names decay implicitly to fun=
ction pointers without requiring the application of operator&amp;. That&#39=
;s not the case with PMFs, which were added in C++. So if PMFs required exp=
licit dereference to be called it would actually be consistent. <br><br>I d=
o not have a preference myself, just wanted to expand on the topic.</div><b=
r>-- gpd<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_520_838473568.1454593998428--
------=_Part_519_1985893359.1454593998428--

.


Author: Alisdair Meredith <alisdairm@me.com>
Date: Thu, 04 Feb 2016 09:03:21 -0500
Raw View
--Apple-Mail=_3997DC5A-A3B7-435C-9724-4E7CDA0BFA5E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

This is not the first time we have seen such a proposal, I remember present=
ing
on behalf of Peter Dimov back in 2004:
  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1695

Sadly, I don=E2=80=99t have a record of why it was rejected back then, but =
Daveed
Vandevoorde instantly jumped to some dark corners of the grammar that
would, in some cases, seem to require support for contradictory requirement=
s.

As I had thought the matter seemed simple and obvious before presenting, I =
was
caught out and not able to catch up with Daveed=E2=80=99s insight (I am not=
 a compiler guy!)
but unfortunately this predates the committee use of wikis to record discus=
sion, and
I don=E2=80=99t remember the precise issue that had to be solved.

I=E2=80=99m hoping someone else can chime in with the relevant insight, as =
solving this
would greatly simplify some forwarding problems for library writers.  On th=
e other
hand, I don=E2=80=99t think the compiler folks invented an obscure syntax t=
o invoke functions
through member pointers just for fun!

AlisdairM


> On Feb 2, 2016, at 1:30 PM, barry.revzin@gmail.com wrote:
>=20
> [func.require] brings up the aggressively shouty INVOKE(f, t1, t2, ..., t=
N) with 5 special cases each to handle pointers-to-member-functions (called=
 on references or pointers) and pointers to member-data (called on referenc=
es or pointers) or normal free functions. This is complicated. We also get =
INVOKE(f, t1, t2, ..., tN, R) to cast the result. We then get [func.invoke]=
 to provide a std::invoke() which does an INVOKE. std::bind() and std::func=
tion<> handle all these separate subcases internally in what I'm sure is a =
lot more lines of code than anybody wants it to be. All of this to do what =
is really one of the simplest operations we have: calling a member function=
..
>=20
> How about we just simplify this and make pointers-to-member functions/dat=
a actually themselves invokable? So given:
>=20
> struct Foo {
>    int bar(char );
> };
>=20
> Foo foo{...};
> Foo *pfoo =3D &foo;
> auto op =3D &Foo::bar;
>=20
> We already have a few different ways of calling op on f with some char:
>=20
> int a =3D (foo.*op)('a');=20
> int b =3D (pfoo->*op)('b');
> int c =3D std::invoke(op, foo, 'c');
> int d =3D std::invoke(op, pfoo, 'd');
> int e =3D std::bind(op, foo, 'e')();
>=20
> Let's just add the most obvious one that we're missing:
>=20
> int f =3D op(foo, 'f');
> int g =3D op(pfoo, 'g');
>=20
> This makes a function call actually look like a function call. It's clear=
 and unambiguous. And it would probably obviate the need for std::invoke() =
too.
>=20
> As a friendly extension, the next logical step would be to have these thr=
ee be equivalent:
>=20
> auto op1 =3D [foo](auto&&... args){ return foo.bar(std::forward<decltype(=
args)>(args)...); };
> auto op2 =3D std::bind(&Foo::bar, foo, _all); // from N4171. More concise=
, easier to remember, but doesn't support overloading names
> auto op3 =3D foo.bar;
>=20
> Because who really wants to ever type the first two, anyway?=20
>=20
> --=20
>=20
> ---=20
> You received this message because you are subscribed to the Google Groups=
 "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
 email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-prop=
osals/ <https://groups.google.com/a/isocpp.org/group/std-proposals/>.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

--Apple-Mail=_3997DC5A-A3B7-435C-9724-4E7CDA0BFA5E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D"">This is not the fi=
rst time we have seen such a proposal, I remember presenting<div class=3D""=
>on behalf of Peter Dimov back in 2004:</div><div class=3D"">&nbsp; <a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1695" class=3D=
"">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1695</a></div><=
div class=3D""><br class=3D""></div><div class=3D"">Sadly, I don=E2=80=99t =
have a record of why it was rejected back then, but Daveed</div><div class=
=3D"">Vandevoorde instantly jumped to some dark corners of the grammar that=
</div><div class=3D"">would, in some cases, seem to require support for con=
tradictory requirements.</div><div class=3D""><br class=3D""></div><div cla=
ss=3D"">As I had thought the matter seemed simple and obvious before presen=
ting, I was</div><div class=3D"">caught out and not able to catch up with D=
aveed=E2=80=99s insight (I am not a compiler guy!)</div><div class=3D"">but=
 unfortunately this predates the committee use of wikis to record discussio=
n, and</div><div class=3D"">I don=E2=80=99t remember the precise issue that=
 had to be solved.</div><div class=3D""><br class=3D""></div><div class=3D"=
">I=E2=80=99m hoping someone else can chime in with the relevant insight, a=
s solving this</div><div class=3D"">would greatly simplify some forwarding =
problems for library writers. &nbsp;On the other</div><div class=3D"">hand,=
 I don=E2=80=99t think the compiler folks invented an obscure syntax to inv=
oke functions</div><div class=3D"">through member pointers just for fun!</d=
iv><div class=3D""><br class=3D""></div><div class=3D"">AlisdairM</div><div=
 class=3D""><br class=3D""></div><div class=3D""><br class=3D""><div><block=
quote type=3D"cite" class=3D""><div class=3D"">On Feb 2, 2016, at 1:30 PM, =
<a href=3D"mailto:barry.revzin@gmail.com" class=3D"">barry.revzin@gmail.com=
</a> wrote:</div><br class=3D"Apple-interchange-newline"><div class=3D""><d=
iv dir=3D"ltr" class=3D"">[func.require] brings up the aggressively shouty =
<i class=3D"">INVOKE</i>(f, t1, t2, ..., tN) with 5 special cases each to h=
andle pointers-to-member-functions (called on references or pointers) and p=
ointers to member-data (called on references or pointers) or normal free fu=
nctions. This is complicated. We also get <i class=3D"">INVOKE</i>(f, t1, t=
2, ..., tN, R) to cast the result. We then get [func.invoke] to provide a s=
td::invoke() which does an <i class=3D"">INVOKE</i>. std::bind() and std::f=
unction&lt;&gt; handle all these separate subcases internally in what I'm s=
ure is a lot more lines of code than anybody wants it to be. All of this to=
 do what is really one of the simplest operations we have: calling a member=
 function.<div class=3D""><br class=3D""></div><div class=3D"">How about we=
 just simplify this and make pointers-to-member functions/data actually the=
mselves invokable? So given:</div><div class=3D""><br class=3D""></div><div=
 class=3D""><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, =
187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Foo</span><font color=3D"#666600" class=3D""><span style=3D"=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"" class=3D"styled-by-prettif=
y"><br class=3D"">&nbsp; &nbsp;</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"" class=3D"styled-by-prettify=
"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><s=
pan style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"" class=3D"style=
d-by-prettify"><br class=3D""></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">};</span><span style=3D"" class=3D"styled-by-prettify">=
<br class=3D""><br class=3D""></span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Foo</span><span style=3D"" class=3D"styled-by-prettify"=
> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{...}=
;</span><span style=3D"" class=3D"styled-by-prettify"><br class=3D""></span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span =
style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">*</span><span style=3D"" class=3D"styled-by-=
prettify">pfoo </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=
=3D"" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"" class=3D"styled-by-pre=
ttify"><br class=3D""></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"" class=3D"styled-by-prettify"> op </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #606;"=
 class=3D"styled-by-prettify">Foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"" class=3D"styled-by-pretti=
fy">bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"" class=3D"styled-by-prettify"><br class=3D""></span></=
font></div></code></div><br class=3D"">We already have a few different ways=
 of calling op on f with some char:</div><div class=3D""><br class=3D""></d=
iv><div class=3D""><div class=3D"prettyprint" style=3D"border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 25=
0);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><font class=
=3D""><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"" class=3D"styled-by-prettify"> a </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"" class=3D"styled-by-prettify">foo</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">.*</span><span sty=
le=3D"" class=3D"styled-by-prettify">op</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)(</span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">'a'</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span><span style=3D"" class=3D"styled-by-prettify"> <br c=
lass=3D""></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"" class=3D"styled-by-prettify"> b </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D""=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"" class=3D"styled-by-prettify">=
pfoo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;*=
</span><span style=3D"" class=3D"styled-by-prettify">op</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">'b'</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><span style=3D"" class=3D"styled-b=
y-prettify"><br class=3D""></span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"" class=3D"styled-by-prettify"> c=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"" class=3D=
"styled-by-prettify">invoke</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"" class=3D"styled-by-prettify">op</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"" class=3D"styled-by-prettify"> foo</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">'c'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
;</span><span style=3D"" class=3D"styled-by-prettify"><br class=3D""></span=
></font><font color=3D"#008800" class=3D""><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"" class=3D"styled-by-pre=
ttify"> d </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"" class=3D"styled-by-prettify"> std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D""=
 class=3D"styled-by-prettify">invoke</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"" class=3D"styled-by-prett=
ify">op</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"" class=3D"styled-by-prettify"> pfoo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">'d'</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">);</span><span style=3D"" class=3D"styled-by-prettify"><br class=
=3D""></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int<=
/span><span style=3D"" class=3D"styled-by-prettify"> e </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"" c=
lass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"" class=3D"styled-by-pretti=
fy">bind</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"" class=3D"styled-by-prettify">op</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">'e'</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)();</span><span st=
yle=3D"" class=3D"styled-by-prettify"><br class=3D""></span></font></div></=
code></div><br class=3D"">Let's just add the most obvious one that we're mi=
ssing:</div><div class=3D""><br class=3D""></div><div class=3D""><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"" class=3D"styled-by-prettify"> f=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><font class=3D""><span style=3D"" class=3D"styled-by-prettify"> op</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
f'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
><span style=3D"" class=3D"styled-by-prettify"><br class=3D""></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"" class=3D"styled-by-prettify"> g </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"" class=3D"styled-by-p=
rettify"> op</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"" class=3D"styled-by-prettify">pfoo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">'g'</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span></font></div></code></div><br class=3D"">This makes a=
 function call actually look like a function call. It's clear and unambiguo=
us. And it would probably obviate the need for std::invoke() too.</div><div=
 class=3D""><br class=3D""></div><div class=3D"">As a friendly extension, t=
he next logical step would be to have these three be equivalent:<br class=
=3D""></div><div class=3D""><br class=3D""></div><div class=3D""><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">auto</span><span style=3D"" class=3D"styled-by-prettify"> =
op1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">[</span><span style=3D"" class=3D"=
styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">](</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;&amp;...</span><span style=3D"" class=3D"styled-by-prettify"> args</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">){</span><span =
style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">return</span><span style=3D"" class=3D"style=
d-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">.</span><span style=3D"" class=3D"styled-by-prettify">bar</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"" class=3D"styled-by-pr=
ettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
ecltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"" class=3D"styled-by-prettify">args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)&gt;(</span><span style=3D"=
" class=3D"styled-by-prettify">args</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)...);</span><span style=3D"" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
};</span><span style=3D"" class=3D"styled-by-prettify"><br class=3D""></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"" class=3D"styled-by-prettify"> op2 </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"" class=3D"st=
yled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"" class=3D"styled-by-prettify">bind</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(&amp;</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D""=
 class=3D"styled-by-prettify">bar</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"" class=3D"styled-by-prettif=
y"> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"" class=3D"styled-by-prettify"> _all</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// from N4171. More concise, easier to remember, but does=
n't support overloading names</span><span style=3D"" class=3D"styled-by-pre=
ttify"><br class=3D""></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"" class=3D"styled-by-prettify"> op3 <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"" class=3D"styled-by-prettify"> foo</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">.</span><span style=3D"" class=3D"st=
yled-by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"" class=3D"styled-by-prettify"><br class=
=3D""></span></div></code></div><br class=3D"">Because who really wants to =
ever type the first two, anyway?&nbsp;</div></div><div class=3D""><br class=
=3D"webkit-block-placeholder"></div>

-- <br class=3D"">
<br class=3D"">
--- <br class=3D"">
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br class=3D"">
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" class=3D"">=
std-proposals+unsubscribe@isocpp.org</a>.<br class=3D"">
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" class=3D"">std-proposals@isocpp.org</a>.<br class=3D"">
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" class=3D"">https://groups.google.com/a/isocpp.org/group/st=
d-proposals/</a>.<br class=3D"">
</div></blockquote></div><br class=3D""></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

--Apple-Mail=_3997DC5A-A3B7-435C-9724-4E7CDA0BFA5E--

.


Author: barry.revzin@gmail.com
Date: Sun, 7 Feb 2016 07:22:22 -0800 (PST)
Raw View
------=_Part_1665_2009458598.1454858542474
Content-Type: multipart/alternative;
 boundary="----=_Part_1666_765751413.1454858542475"

------=_Part_1666_765751413.1454858542475
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Thanks everybody for the responses.

Alisdair - yeah I'd love to see this proposal simply resubmitted, to hear=
=20
what the objection was. To T.C.'s point, I don't doubt that there will be=
=20
some SFINAE code that would be broken (or lead to some ambiguous overloads=
=20
where it was previously unambiguous or something else unexpected). But=20
fundamentally, a pointer-to-member function shouldn't really any different=
=20
than a normal pointer-to-function that must take an object (or=20
reference_wrapper or smart pointer) as its first argument. So it's, in my=
=20
view, inconsistent that the things we can do with pointers-to-functions=20
(simply use them as callables), we can't do with pointers-to-member=20
functions (with which we have to jump through hoops).=20

Of course, we could take the next step too but maybe I'm pushing it here:

struct X {
   int bar();
};

int (*pf)(X*) =3D [](X* x){ return x->bar(); }; // we can already do this
int (*pf2)(X*) =3D &X::bar;                     // so why not allow this to=
o?



On Thursday, February 4, 2016 at 8:03:26 AM UTC-6, Alisdair Meredith wrote:
>
> This is not the first time we have seen such a proposal, I remember=20
> presenting
> on behalf of Peter Dimov back in 2004:
>   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1695
>
> Sadly, I don=E2=80=99t have a record of why it was rejected back then, bu=
t Daveed
> Vandevoorde instantly jumped to some dark corners of the grammar that
> would, in some cases, seem to require support for contradictory=20
> requirements.
>
> As I had thought the matter seemed simple and obvious before presenting, =
I=20
> was
> caught out and not able to catch up with Daveed=E2=80=99s insight (I am n=
ot a=20
> compiler guy!)
> but unfortunately this predates the committee use of wikis to record=20
> discussion, and
> I don=E2=80=99t remember the precise issue that had to be solved.
>
> I=E2=80=99m hoping someone else can chime in with the relevant insight, a=
s solving=20
> this
> would greatly simplify some forwarding problems for library writers.  On=
=20
> the other
> hand, I don=E2=80=99t think the compiler folks invented an obscure syntax=
 to=20
> invoke functions
> through member pointers just for fun!
>
> AlisdairM
>
>
> On Feb 2, 2016, at 1:30 PM, barry....@gmail.com <javascript:> wrote:
>
> [func.require] brings up the aggressively shouty *INVOKE*(f, t1, t2, ...,=
=20
> tN) with 5 special cases each to handle pointers-to-member-functions=20
> (called on references or pointers) and pointers to member-data (called on=
=20
> references or pointers) or normal free functions. This is complicated. We=
=20
> also get *INVOKE*(f, t1, t2, ..., tN, R) to cast the result. We then get=
=20
> [func.invoke] to provide a std::invoke() which does an *INVOKE*.=20
> std::bind() and std::function<> handle all these separate subcases=20
> internally in what I'm sure is a lot more lines of code than anybody want=
s=20
> it to be. All of this to do what is really one of the simplest operations=
=20
> we have: calling a member function.
>
> How about we just simplify this and make pointers-to-member functions/dat=
a=20
> actually themselves invokable? So given:
>
> struct Foo {
>    int bar(char );
> };
>
> Foo foo{...};
> Foo *pfoo =3D &foo;
> auto op =3D &Foo::bar;
>
> We already have a few different ways of calling op on f with some char:
>
> int a =3D (foo.*op)('a');=20
> int b =3D (pfoo->*op)('b');
> int c =3D std::invoke(op, foo, 'c');
> int d =3D std::invoke(op, pfoo, 'd');
> int e =3D std::bind(op, foo, 'e')();
>
> Let's just add the most obvious one that we're missing:
>
> int f =3D op(foo, 'f');
> int g =3D op(pfoo, 'g');
>
> This makes a function call actually look like a function call. It's clear=
=20
> and unambiguous. And it would probably obviate the need for std::invoke()=
=20
> too.
>
> As a friendly extension, the next logical step would be to have these=20
> three be equivalent:
>
> auto op1 =3D [foo](auto&&... args){ return foo.bar(std::forward<decltype(
> args)>(args)...); };
> auto op2 =3D std::bind(&Foo::bar, foo, _all); // from N4171. More concise=
,=20
> easier to remember, but doesn't support overloading names
> auto op3 =3D foo.bar;
>
> Because who really wants to ever type the first two, anyway?=20
>
> --=20
>
> ---=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.

------=_Part_1666_765751413.1454858542475
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thanks everybody for the responses.<div><br></div><div>Ali=
sdair - yeah I&#39;d love to see this proposal simply resubmitted, to hear =
what the objection was. To T.C.&#39;s point, I don&#39;t doubt that there w=
ill be some SFINAE code that would be broken (or lead to some ambiguous ove=
rloads where it was previously unambiguous or something else unexpected). B=
ut fundamentally, a pointer-to-member function shouldn&#39;t really any dif=
ferent than a normal pointer-to-function that must take an object (or refer=
ence_wrapper or smart pointer) as its first argument. So it&#39;s, in my vi=
ew, inconsistent that the things we can do with pointers-to-functions (simp=
ly use them as callables), we can&#39;t do with pointers-to-member function=
s (with which we have to jump through hoops).=C2=A0</div><div><br></div><di=
v>Of course, we could take the next step too but maybe I&#39;m pushing it h=
ere:</div><div><br></div><div><div class=3D"prettyprint" style=3D"border: 1=
px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(2=
50, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><=
span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> X </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(*</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">pf</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">X</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">*)</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">[](</span><span style=3D"color: #000;" class=3D"styled-by-prettify">X<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">){</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">-&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// we can already do this</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(*</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">pf</span><font color=3D"#666600"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">2</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">X</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*)</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">X</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">bar</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// so why not allow this too?</span></font><font color=3D"#6=
66600"></font></div></code></div><br><br><br>On Thursday, February 4, 2016 =
at 8:03:26 AM UTC-6, Alisdair Meredith wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div style=3D"word-wrap:break-word">This is not the first ti=
me we have seen such a proposal, I remember presenting<div>on behalf of Pet=
er Dimov back in 2004:</div><div>=C2=A0 <a href=3D"http://www.open-std.org/=
jtc1/sc22/wg21/docs/papers/2004/n1695" target=3D"_blank" rel=3D"nofollow" o=
nmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fw=
ww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2004%2Fn1695\46sa\75=
D\46sntz\0751\46usg\75AFQjCNF9OVHHd0CMzOlP_ytjl3x5S-i9-Q&#39;;return true;"=
 onclick=3D"this.href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fwww=
..open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2004%2Fn1695\46sa\75D\=
46sntz\0751\46usg\75AFQjCNF9OVHHd0CMzOlP_ytjl3x5S-i9-Q&#39;;return true;">h=
ttp://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2004/<wbr>n1695</a><=
/div><div><br></div><div>Sadly, I don=E2=80=99t have a record of why it was=
 rejected back then, but Daveed</div><div>Vandevoorde instantly jumped to s=
ome dark corners of the grammar that</div><div>would, in some cases, seem t=
o require support for contradictory requirements.</div><div><br></div><div>=
As I had thought the matter seemed simple and obvious before presenting, I =
was</div><div>caught out and not able to catch up with Daveed=E2=80=99s ins=
ight (I am not a compiler guy!)</div><div>but unfortunately this predates t=
he committee use of wikis to record discussion, and</div><div>I don=E2=80=
=99t remember the precise issue that had to be solved.</div><div><br></div>=
<div>I=E2=80=99m hoping someone else can chime in with the relevant insight=
, as solving this</div><div>would greatly simplify some forwarding problems=
 for library writers. =C2=A0On the other</div><div>hand, I don=E2=80=99t th=
ink the compiler folks invented an obscure syntax to invoke functions</div>=
<div>through member pointers just for fun!</div><div><br></div><div>Alisdai=
rM</div><div><br></div><div><br><div><blockquote type=3D"cite"><div>On Feb =
2, 2016, at 1:30 PM, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscat=
ed-mailto=3D"VllQuB2UHAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39=
;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39=
;;return true;">barry....@gmail.com</a> wrote:</div><br><div><div dir=3D"lt=
r">[func.require] brings up the aggressively shouty <i>INVOKE</i>(f, t1, t2=
, ..., tN) with 5 special cases each to handle pointers-to-member-functions=
 (called on references or pointers) and pointers to member-data (called on =
references or pointers) or normal free functions. This is complicated. We a=
lso get <i>INVOKE</i>(f, t1, t2, ..., tN, R) to cast the result. We then ge=
t [func.invoke] to provide a std::invoke() which does an <i>INVOKE</i>. std=
::bind() and std::function&lt;&gt; handle all these separate subcases inter=
nally in what I&#39;m sure is a lot more lines of code than anybody wants i=
t to be. All of this to do what is really one of the simplest operations we=
 have: calling a member function.<div><br></div><div>How about we just simp=
lify this and make pointers-to-member functions/data actually themselves in=
vokable? So given:</div><div><br></div><div><div style=3D"border:1px solid =
rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><c=
ode><div><span style=3D"color:#008">struct</span><span> </span><span style=
=3D"color:#606">Foo</span><font color=3D"#666600"><span> </span><span style=
=3D"color:#660">{</span><span><br>=C2=A0 =C2=A0</span><span style=3D"color:=
#008">int</span><span> bar</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#008">char</span><span> </span><span style=3D"color:#660">);<=
/span><span><br></span><span style=3D"color:#660">};</span><span><br><br></=
span><span style=3D"color:#606">Foo</span><span> foo</span><span style=3D"c=
olor:#660">{...};</span><span><br></span><span style=3D"color:#606">Foo</sp=
an><span> </span><span style=3D"color:#660">*</span><span>pfoo </span><span=
 style=3D"color:#660">=3D</span><span> </span><span style=3D"color:#660">&a=
mp;</span><span>foo</span><span style=3D"color:#660">;</span><span><br></sp=
an><span style=3D"color:#008">auto</span><span> op </span><span style=3D"co=
lor:#660">=3D</span><span> </span><span style=3D"color:#660">&amp;</span><s=
pan style=3D"color:#606">Foo</span><span style=3D"color:#660">::</span><spa=
n>bar</span><span style=3D"color:#660">;</span><span><br></span></font></di=
v></code></div><br>We already have a few different ways of calling op on f =
with some char:</div><div><br></div><div><div style=3D"border:1px solid rgb=
(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code=
><div><font><span style=3D"color:#008">int</span><span> a </span><span styl=
e=3D"color:#660">=3D</span><span> </span><span style=3D"color:#660">(</span=
><span>foo</span><span style=3D"color:#660">.*</span><span>op</span><span s=
tyle=3D"color:#660">)(</span><span style=3D"color:#080">&#39;a&#39;</span><=
span style=3D"color:#660">);</span><span> <br></span><span style=3D"color:#=
008">int</span><span> b </span><span style=3D"color:#660">=3D</span><span> =
</span><span style=3D"color:#660">(</span><span>pfoo</span><span style=3D"c=
olor:#660">-&gt;*</span><span>op</span><span style=3D"color:#660">)(</span>=
<span style=3D"color:#080">&#39;b&#39;</span><span style=3D"color:#660">);<=
/span><span><br></span><span style=3D"color:#008">int</span><span> c </span=
><span style=3D"color:#660">=3D</span><span> std</span><span style=3D"color=
:#660">::</span><span>invoke</span><span style=3D"color:#660">(</span><span=
>op</span><span style=3D"color:#660">,</span><span> foo</span><span style=
=3D"color:#660">,</span><span> </span><span style=3D"color:#080">&#39;c&#39=
;</span><span style=3D"color:#660">);</span><span><br></span></font><font c=
olor=3D"#008800"><span style=3D"color:#008">int</span><span> d </span><span=
 style=3D"color:#660">=3D</span><span> std</span><span style=3D"color:#660"=
>::</span><span>invoke</span><span style=3D"color:#660">(</span><span>op</s=
pan><span style=3D"color:#660">,</span><span> pfoo</span><span style=3D"col=
or:#660">,</span><span> </span><span style=3D"color:#080">&#39;d&#39;</span=
><span style=3D"color:#660">);</span><span><br></span><span style=3D"color:=
#008">int</span><span> e </span><span style=3D"color:#660">=3D</span><span>=
 std</span><span style=3D"color:#660">::</span><span>bind</span><span style=
=3D"color:#660">(</span><span>op</span><span style=3D"color:#660">,</span><=
span> foo</span><span style=3D"color:#660">,</span><span> </span><span styl=
e=3D"color:#080">&#39;e&#39;</span><span style=3D"color:#660">)();</span><s=
pan><br></span></font></div></code></div><br>Let&#39;s just add the most ob=
vious one that we&#39;re missing:</div><div><br></div><div><div style=3D"bo=
rder:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(2=
50,250,250)"><code><div><span style=3D"color:#008">int</span><span> f </spa=
n><span style=3D"color:#660">=3D</span><font><span> op</span><span style=3D=
"color:#660">(</span><span>foo</span><span style=3D"color:#660">,</span><sp=
an> </span><span style=3D"color:#080">&#39;f&#39;</span><span style=3D"colo=
r:#660">);</span><span><br></span><span style=3D"color:#008">int</span><spa=
n> g </span><span style=3D"color:#660">=3D</span><span> op</span><span styl=
e=3D"color:#660">(</span><span>pfoo</span><span style=3D"color:#660">,</spa=
n><span> </span><span style=3D"color:#080">&#39;g&#39;</span><span style=3D=
"color:#660">);</span></font></div></code></div><br>This makes a function c=
all actually look like a function call. It&#39;s clear and unambiguous. And=
 it would probably obviate the need for std::invoke() too.</div><div><br></=
div><div>As a friendly extension, the next logical step would be to have th=
ese three be equivalent:<br></div><div><br></div><div><div style=3D"border:=
1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,25=
0,250)"><code><div><span style=3D"color:#008">auto</span><span> op1 </span>=
<span style=3D"color:#660">=3D</span><span> </span><span style=3D"color:#66=
0">[</span><span>foo</span><span style=3D"color:#660">](</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;...</span><=
span> args</span><span style=3D"color:#660">){</span><span> </span><span st=
yle=3D"color:#008">return</span><span> foo</span><span style=3D"color:#660"=
>.</span><span>bar</span><span style=3D"color:#660">(</span><span>std</span=
><span style=3D"color:#660">::</span><span>forward</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">decltype</span><span style=
=3D"color:#660">(</span><span><wbr>args</span><span style=3D"color:#660">)&=
gt;(</span><span>args</span><span style=3D"color:#660">)...);</span><span> =
</span><span style=3D"color:#660">};</span><span><br></span><span style=3D"=
color:#008">auto</span><span> op2 </span><span style=3D"color:#660">=3D</sp=
an><span> std</span><span style=3D"color:#660">::</span><span>bind</span><s=
pan style=3D"color:#660">(&amp;</span><span style=3D"color:#606">Foo</span>=
<span style=3D"color:#660">::</span><span>bar</span><span style=3D"color:#6=
60">,</span><span> foo</span><span style=3D"color:#660">,</span><span> _all=
</span><span style=3D"color:#660">);</span><span> </span><span style=3D"col=
or:#800">// from N4171. More concise, easier to remember, but doesn&#39;t s=
upport overloading names</span><span><br></span><span style=3D"color:#008">=
auto</span><span> op3 </span><span style=3D"color:#660">=3D</span><span> fo=
o</span><span style=3D"color:#660">.</span><span>bar</span><span style=3D"c=
olor:#660">;</span><span><br></span></div></code></div><br>Because who real=
ly wants to ever type the first two, anyway?=C2=A0</div></div><div><br></di=
v>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
VllQuB2UHAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"VllQuB2UHAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D&#39;https://groups.google.com/a/isocpp.org/group/std-proposals/&#39;;r=
eturn true;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp=
..org/group/std-proposals/&#39;;return true;">https://groups.google.com/a/<w=
br>isocpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></blockquote></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_1666_765751413.1454858542475--
------=_Part_1665_2009458598.1454858542474--

.