Topic: [c++std-core-27175] An implementation of
Author: Jonathan Wakely <cxx@kayari.org>
Date: Wed, 4 Mar 2015 11:13:49 +0000
Raw View
On 4 March 2015 at 05:36, Arthur O'Dwyer wrote:
>>
>> 2) Abbreviated Template Syntax:
>> void f(auto) <=> template<class T> void f(T);
>
>
> THIS is the very very awesome part. I am super excited about this feature
> finally coming to a compiler near me!
Like GCC 4.9, released a year ago? :-)
https://gcc.gnu.org/gcc-4.9/changes.html#cxx
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "'Geoffrey Romer' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 4 Mar 2015 09:59:44 -0800
Raw View
--089e01494d54626b8005107a3778
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tue, Mar 3, 2015 at 9:36 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
> On Tuesday, March 3, 2015 at 6:39:49 PM UTC-8, faisalv wrote:
>>
>> In the hopes of soliciting constructive feedback, if anyone has the
>> time or the interest to play with a patched up Clang that implements
>> enhanced auto deduction & abbreviated template syntax from the
>> concepts ts, here it is:
>>
>> https://github.com/faisalv/clang/tree/enhanced-auto-c%2B%2B1z .
>>
>
> That's *very very cool* =E2=80=94 at least the "abbreviated template synt=
ax"
> half! ;)
>
Interesting; my reaction is precisely the opposite- I find enhanced auto
deduction very appealing (for reasons that others on this thread have
elaborated), but am actively uninterested in the abbreviated template
syntax. It seems to me to offer only a modest improvement in brevity, and
pays for it with a very substantial reduction in readability. That
compromise may be appropriate for lambdas, because brevity is particularly
important inside a single expression, but it seems far less justifiable in
the case of ordinary functions. Functions are not under the kinds of space
constraints that lambdas are, and function signatures (unlike lambda
signatures) often act as abstraction boundaries, so it's particularly
important for them to convey useful information to the reader.
> Is it possible for you to separate out the "abbreviated template syntax"
> feature from the "enhanced auto detection" feature, into two separate
> patches that could be looked at and/or adopted individually?
>
> Now that we have generic lambdas (in C++14), I'm looking forward to havin=
g
> "generic functions" (i.e., abbreviated template syntax) sooner rather tha=
n
> later.
>
> // C++14: Create a lambda object with a template member operator()
> auto f =3D [](auto x, auto y) { return x + y; };
>
> // C++1z: Create a template function directly
> auto f(auto x, auto y) { return x + y; }
>
>
> 1) Enhanced-Auto Deduction:
>>
>> pair<auto...> f() { return make_pair([] { }, [] { }); }
>> vector<auto> v =3D vector<int>();
>>
>
> I don't see the use-case for this feature. Why would I write
>
> vector<auto> v =3D vector<int>();
>
> when it's less typing and less noise to just write
>
> auto v =3D vector<int>();
>
> ? Also, as you noted in technicality (d), it's impossible to support
> "enhanced deduction" for type aliases. I don't like the asymmetry this
> creates between "class types" and "typedef types". Here are a collection
> of "enhanced" cases where deduction fails (in some cases, MUST fail).
>
> template<class T> using identity1 =3D T;
> identity1<auto> id1 =3D 42;
> template<class T> struct identity2 { using type =3D T; };
> identity2<auto>::type id2 =3D 42;
> template<class T> struct int3 { using type =3D int; };
> int3<auto>::type id3 =3D 42;
> template<class> using int4 =3D int;
> int4<auto> id4 =3D 42;
>
> I'm mostly concerned with the fact that you're making identity1<auto>
> fail, while vector<auto> succeeds.
>
> Here's a use-case I could maybe get behind:
>
> vector<auto> vec =3D { 1, 2, 3 }; // creates a vector of int
>
> except that (correct me if I'm wrong) your patch doesn't support that
> use-case. And I'm not sure how it could.
>
>
>> 2) Abbreviated Template Syntax:
>> void f(auto) <=3D> template<class T> void f(T);
>>
>
> THIS is the very very awesome part. I am super excited about this feature
> finally coming to a compiler near me!
>
> A few, perhaps not so obvious or interesting, technicalities:
>>
>> a) The equivalence of templates when it comes to trailing return
>> types in function pointer parameters is based on the order of the
>> 'auto' that signifies a placeholder, not just the appearance of an
>> auto in the declaration-specifier of a parameter:
>>
>> template<class R, class P> void f( R(P) ); // #1
>> template<class P, class R> void f( R(P) ); // #2 (order of
>> templ-params flipped)
>>
>> template<class R, class P> void f( auto (P)->R); // equivalent to
>> #1, not abbreviated.
>>
>
> How many of these weirdnesses vanish if you get rid of "enhanced auto
> deduction"?
> Clang 3.7.0 doesn't currently allow trailing return types on C++14 generi=
c
> lambda parameters, which IMHO is a feature (in that allowing them leads t=
o
> the grotesqueries you mention) but I'm pretty sure from the Standard's PO=
V
> is a bug. (Contrariwise, I think GCC 5.0.0 is *too* permissive. But in
> neither case am I sure exactly what's allowed by the Standard.)
>
> http://melpon.org/wandbox/permlink/QMQXHNsBmwVJbxM0
> int one(int (*f)(int)) { return f(42); } // C++03
> int two(auto (*f)(int) -> int) { return f(42); } // C++11
> int three(auto (*f)(int)) { return f(42); } // never
> int four(auto (*f)(int) -> auto) { return f(42); } // never
> int five(int (*f)(auto)) { return f(42); } // never
> int six(int f(int)) { return f(42); } // C++03 (takes a function pointer=
)
> int seven(int f(auto)) { return f(42); } // never
>
>
> auto bone =3D [](int (*f)(int)) { return f(42); }; // C++11
> auto btwo =3D [](auto (*f)(int) -> int) { return f(42); }; // never
> auto bthree =3D [](auto (*f)(int)) { return f(42); }; // C++14
> auto bfour =3D [](auto (*f)(int) -> auto) { return f(42); }; // never
> auto bfive =3D [](int (*f)(auto)) { return f(42); }; // never
> auto bsix =3D [](int f(int)) { return f(42); }; // C++11 (takes a functi=
on
> pointer)
> auto bseven =3D [](int f(auto)) { return f(42); }; // never
>
>
>
>> void f(auto(auto)); // equivalent to #1
>>
>
> IMHO, this should be disallowed. It deduces a function type for the
> parameter, and then "decays" that type to a function pointer, in the same
> way that parameters of array type "decay" to pointers. This was inherited
> from C, is super confusing, and in an age of generic lambda functors real=
ly
> deserves to be put to bed.
>
> auto f(auto ga(auto)) { return ga("hello world"); }
> auto g(auto xa) { puts(xa); }
> int main() { f(g); }
>
> Today, even though it looks like ga and g have the same type, they don't!
> g is a function *template*, and ga is a *pointer to a function of
> unspecified type*.
> The idiomatically correct signature for f IMHO would be
>
> auto f(auto *ga) { return ga("hello world"); }
>
>
> b) variadic auto
>> Once an ellipsis is seen as part of the declarator, all contained
>> auto placeholders get transformed into parameter packs.
>> void f(auto (*...)(auto) -> std::tuple<auto, std::pair<auto,
>> auto>...>);
>> Note there are 4 deducible template parameter packs above.
>>
>
> Do I understand correctly that the above is exactly equivalent to
>
> template<class... A, class... B, class... C, class... D>
> void f1(std::tuple<A, std::pair<B,C>...> (*...args)(D));
>
> void f2(std::tuple<auto, std::pair<auto,auto>...> (*...args)(auto));
>
> where f1 uses C++11 syntax and f2 uses only "abbreviated template" syntax=
?
>
> c) multi abbreviated template declarations
>> void f(auto), g(auto);
>> are allowed - the above declares two function templates.
>>
>
> That's not allowed for non-abbreviated templates, and again I don't see a
> use-case for it. What's a case where I would want to chain together
> function declarations like that? Again, that seems like cruft inherited
> from C that could easily be dumped at least for new syntax.
>
> You don't mention this as a pitfall, but looking at your test cases I
> observed that
>
> auto foo =3D 42; // foo is definitely an int
> void bar(auto baz =3D 42); // baz is NOT an int; it's of some deduce=
d
> type.
> // The initializer 42 is coerced to that
> type if necessary.
>
> Consider the following progression:
>
> template<class X, class Y=3Dint> auto one(X x, Y y=3D1) { return x+y; }; =
//
> legal C++14
> template<class X, class Y> auto two(X x, Y y=3D1) { return x+y; }; //
> invalid, and rightly so
> auto three =3D [](auto x, auto y=3D1) { return x+y; }; // invalid, but I
> claim it has an obvious meaning that should be standardized
> auto four(auto x, auto y=3D1) { return x+y; }; // invalid?? with your
> patch, but I claim it has an obvious meaning
> int main() { one(1); two(2); three(3); four(4); }
>
> I know this has been a massive and scattered array of potshots, but I hop=
e
> you find some of it interesting and/or useful. :)
>
> =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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--089e01494d54626b8005107a3778
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Tue, Mar 3, 2015 at 9:36 PM, Arthur O'Dwyer <span dir=3D"ltr"><<a=
href=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwye=
r@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><span class=3D"">On Tuesday, March 3, 2015 at 6:39:49 PM UTC-8, f=
aisalv wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">In the hopes of solici=
ting constructive feedback, if anyone has the
<br>time or the interest to play with a patched up Clang that implements
<br>enhanced auto deduction & abbreviated template syntax from the
<br>concepts ts, here it is:
<br>
<br><a href=3D"https://github.com/faisalv/clang/tree/enhanced-auto-c%2B%2B1=
z" rel=3D"nofollow" target=3D"_blank">https://github.com/faisalv/<u></u>cla=
ng/tree/enhanced-auto-c%2B%<u></u>2B1z</a> .
<br></blockquote><div><br></div></span><div>That's <b>very very cool</b=
> =E2=80=94 at least the "abbreviated template syntax" half! ;)</=
div></div></blockquote><div><br></div><div>Interesting; my reaction is prec=
isely the opposite- I find enhanced auto deduction very appealing (for reas=
ons that others on this thread have elaborated), but am actively uninterest=
ed in the abbreviated template syntax. It seems to me to offer only a modes=
t improvement in brevity, and pays for it with a very substantial reduction=
in readability. That compromise may be appropriate for lambdas, because br=
evity is particularly important inside a single expression, but it seems fa=
r less justifiable in the case of ordinary functions. Functions are not und=
er the kinds of space constraints that lambdas are, and function signatures=
(unlike lambda signatures) often act as abstraction boundaries, so it'=
s particularly important for them to convey useful information to the reade=
r.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv> =C2=A0Is it possible for you to separate out the "abbreviated temp=
late syntax" feature from the "enhanced auto detection" feat=
ure, into two separate patches that could be looked at and/or adopted indiv=
idually?</div><div>=C2=A0</div><div>Now that we have generic lambdas (in C+=
+14), I'm looking forward to having "generic functions" (i.e.=
, abbreviated template syntax) sooner rather than later.</div><div><br></di=
v><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,=
187,187);word-wrap:break-word"><code><div><span style=3D"color:#000">=C2=A0=
=C2=A0 </span><span style=3D"color:#800">// C++14: Create a lambda object =
with a template member operator()</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#000"> f </span><span style=3D"color:#660">=3D</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">[](</span><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> x</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> y</span><span style=3D"color:#660">)</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> x </span><span style=3D"color:#660">+</span><sp=
an style=3D"color:#000"> y</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">// =
C++1z: Create a template function directly</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">auto</span><span style=3D"color:#000"> x</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> y</span><span style=3D"color:#=
660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">retur=
n</span><span style=3D"color:#000"> x </span><span style=3D"color:#660">+</=
span><span style=3D"color:#000"> y</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">}</span></di=
v></code></div><span class=3D""><div><div><br></div></div><div><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex">1) Enhanced-Auto Deduction:
<br>
<br>=C2=A0pair<auto...> f() { return make_pair([] { }, [] { }); }
<br>=C2=A0vector<auto> v =3D vector<int>();
<br></blockquote><div><br></div></span><div>I don't see the use-case fo=
r this feature. Why would I write</div><span class=3D""><div><br></div><div=
><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,1=
87,187);word-wrap:break-word"><code><div><span style=3D"color:#000">=C2=A0 =
=C2=A0 vector</span><span style=3D"color:#080"><auto></span><span sty=
le=3D"color:#000"> v </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> vector</span><span style=3D"color:#080"><int></span=
><span style=3D"color:#660">();</span></div></code></div></div><div><br></d=
iv></span><div>when it's less typing and less noise to just write</div>=
<span class=3D""><div><br></div><div><div style=3D"background-color:rgb(250=
,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><di=
v><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008=
">auto</span><span style=3D"color:#000"> v </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> vector</span><span style=3D"color:#=
080"><int></span><span style=3D"color:#660">();</span></div></code></=
div></div><div><br></div></span><div>? Also, as you noted in technicality (=
d), it's impossible to support "enhanced deduction" for type =
aliases. I don't like the asymmetry this creates between "class ty=
pes" and "typedef types".=C2=A0 Here are a collection of &qu=
ot;enhanced" cases where deduction fails (in some cases, MUST fail).=
=C2=A0</div><div><br></div><div style=3D"background-color:rgb(250,250,250);=
border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span st=
yle=3D"color:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">template=
</span><span style=3D"color:#660"><</span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">using=
</span><span style=3D"color:#000"> identity1 </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 identity1</span><spa=
n style=3D"color:#080"><auto></span><span style=3D"color:#000"> id1 <=
/span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#066">42</span><span style=3D"color:#660">;</span><=
span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">template</span><span style=3D"color:#660"><</span><span style=3D"colo=
r:#008">class</span><span style=3D"color:#000"> T</span><span style=3D"colo=
r:#660">></span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">struct</span><span style=3D"color:#000"> identity2 </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">using</span><span style=3D"color:#000"> type </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 identity2<=
/span><span style=3D"color:#080"><auto></span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">type id2 </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
066">42</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span s=
tyle=3D"color:#660"><</span><span style=3D"color:#008">class</span><span=
style=3D"color:#000"> T</span><span style=3D"color:#660">></span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><span =
style=3D"color:#000"> int3 </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">using</span><span s=
tyle=3D"color:#000"> type </span><span style=3D"color:#660">=3D</span><span=
style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span st=
yle=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 int3<=
/span><span style=3D"color:#080"><auto></span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">type id3 </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
066">42</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span s=
tyle=3D"color:#080"><class></span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">using</span><span style=3D"color:#000"> int4 </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">int</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 int4</span><span style=3D"color:=
#080"><auto></span><span style=3D"color:#000"> id4 </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">42</span><span style=3D"color:#660">;</span></div></code></div=
><div><br></div><div>I'm mostly concerned with the fact that you're=
making identity1<auto> fail, while vector<auto> succeeds.</div=
><div><br></div><div>Here's a use-case I could maybe get behind:</div><=
div><br></div><div><div style=3D"background-color:rgb(250,250,250);border:1=
px solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"c=
olor:#000">=C2=A0 =C2=A0 vector</span><span style=3D"color:#080"><auto&g=
t;</span><span style=3D"color:#000"> vec </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"> </span><span style=3D"color:#066">1</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span=
style=3D"color:#066">2</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#066">3</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">};</span><span style=3D"colo=
r:#000"> =C2=A0</span><span style=3D"color:#800">// creates a vector of int=
</span></div></code></div></div><div><br></div><div>except that (correct me=
if I'm wrong) your patch doesn't support that use-case. And I'=
m not sure how it could.</div><span class=3D""><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex">
<br>2) Abbreviated Template Syntax:
<br>void f(auto) <=3D> template<class T> void f(T);<br></blockq=
uote><div><br></div></span><div>THIS is the very very awesome part. I am su=
per excited about this feature finally coming to a compiler near me!</div><=
span class=3D""><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">A fe=
w, perhaps not so obvious or interesting, technicalities:
<br>
<br>a) =C2=A0The equivalence of templates when it comes to trailing return
<br>types in function pointer parameters is based on the order of the
<br>'auto' that signifies a placeholder, not just the appearance of=
an
<br>auto in the declaration-specifier of a parameter:
<br>
<br>=C2=A0 =C2=A0 template<class R, class P> void f( R(P) ); =C2=A0//=
#1
<br>=C2=A0 =C2=A0 template<class P, class R> void f( =C2=A0R(P) ); =
=C2=A0// #2 (order of
<br>templ-params flipped)
<br>
<br>=C2=A0 =C2=A0 template<class R, class P> void f( auto (P)->R);=
// equivalent to
<br>#1, not abbreviated.
<br></blockquote><div><br></div></span><div>How many of these weirdnesses v=
anish if you get rid of "enhanced auto deduction"?</div><div>Clan=
g 3.7.0 doesn't currently allow trailing return types on C++14 generic =
lambda parameters, which IMHO is a feature (in that allowing them leads to =
the grotesqueries you mention) but I'm pretty sure from the Standard=
9;s POV is a bug. (Contrariwise, I think GCC 5.0.0 is *too* permissive. But=
in neither case am I sure exactly what's allowed by the Standard.)</di=
v><div><br></div><div><a href=3D"http://melpon.org/wandbox/permlink/QMQXHNs=
BmwVJbxM0" target=3D"_blank">http://melpon.org/wandbox/permlink/QMQXHNsBmwV=
JbxM0<br></a></div><div><div style=3D"background-color:rgb(250,250,250);bor=
der:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=
=3D"color:#008">int</span><span style=3D"color:#000"> one</span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">int</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">(*</span><span style=3D"col=
or:#000">f</span><span style=3D"color:#660">)(</span><span style=3D"color:#=
008">int</span><span style=3D"color:#660">))</span><span style=3D"color:#00=
0"> </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"> f=
</span><span style=3D"color:#660">(</span><span style=3D"color:#066">42</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">}</span><span style=3D"color:#000"> =C2=A0</span>=
<span style=3D"color:#800">// C++03</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#008">int</span><span style=3D"color:#000"> two</=
span><span style=3D"color:#660">(</span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">(*</span><=
span style=3D"color:#000">f</span><span style=3D"color:#660">)(</span><span=
style=3D"color:#008">int</span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">-></span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">int</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> f</span><span style=3D"color=
:#660">(</span><span style=3D"color:#066">42</span><span style=3D"color:#66=
0">);</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">=
// C++11</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">int</span><span style=3D"color:#000"> three</span><span style=3D"color=
:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">(*</span><span style=3D"color:#000"=
>f</span><span style=3D"color:#660">)(</span><span style=3D"color:#008">int=
</span><span style=3D"color:#660">))</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">return</span><span style=3D"color:#000"> f</span><=
span style=3D"color:#660">(</span><span style=3D"color:#066">42</span><span=
style=3D"color:#660">);</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">}</span><span style=3D"color:#000"> =C2=A0</span><span st=
yle=3D"color:#800">// never</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#008">int</span><span style=3D"color:#000"> four</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(*</span><span st=
yle=3D"color:#000">f</span><span style=3D"color:#660">)(</span><span style=
=3D"color:#008">int</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">-></span><span style=3D"=
color:#000"> </span><span style=3D"color:#008">auto</span><span style=3D"co=
lor:#660">)</span><span style=3D"color:#000"> </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"> f</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#066">42</span><span style=3D"color:#660">);<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">// nev=
er</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">i=
nt</span><span style=3D"color:#000"> five</span><span style=3D"color:#660">=
(</span><span style=3D"color:#008">int</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">(*</span><span style=3D"color:#000">f</span=
><span style=3D"color:#660">)(</span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#660">))</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">return</span><span style=3D"color:#000"> f</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#066">42</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"> =C2=A0</span><span style=3D=
"color:#800">// never</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">int</span><span style=3D"color:#000"> six</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">int</span><span style=3D"color:#660">))</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">return</span><span style=3D"color:#=
000"> f</span><span style=3D"color:#660">(</span><span style=3D"color:#066"=
>42</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">}</span><span style=3D"color:#000"> =C2=A0=
</span><span style=3D"color:#800">// C++03 (takes a function pointer)</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">int</span=
><span style=3D"color:#000"> seven</span><span style=3D"color:#660">(</span=
><span style=3D"color:#008">int</span><span style=3D"color:#000"> f</span><=
span style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><sp=
an style=3D"color:#660">))</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> f</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#066">42</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">}</span><span style=3D"color:#000"> =C2=A0</span><span style=3D"co=
lor:#800">// never</span><span style=3D"color:#000"><br><br><br></span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> bone </span><=
span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">[](</span><span style=3D"color:#008">int</span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">(*</span><span sty=
le=3D"color:#000">f</span><span style=3D"color:#660">)(</span><span style=
=3D"color:#008">int</span><span style=3D"color:#660">))</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color=
:#066">42</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000">=
=C2=A0</span><span style=3D"color:#800">// C++11</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> btwo </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">[](</span><span style=3D"colo=
r:#008">auto</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">(*</span><span style=3D"color:#000">f</span><span style=3D"color:#660=
">)(</span><span style=3D"color:#008">int</span><span style=3D"color:#660">=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">->=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">return</span><span style=3D"color:#000"> f</span><span=
style=3D"color:#660">(</span><span style=3D"color:#066">42</span><span sty=
le=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">};</span><span style=3D"color:#000"> =C2=A0</span><span sty=
le=3D"color:#800">// never</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> bthree </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">[](</span><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">(*</span><span =
style=3D"color:#000">f</span><span style=3D"color:#660">)(</span><span styl=
e=3D"color:#008">int</span><span style=3D"color:#660">))</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color=
:#066">42</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000">=
=C2=A0</span><span style=3D"color:#800">// C++14</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> bfour </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">[](</span><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">(*</span><span style=3D"color:#000">f</span><span style=3D"color:#66=
0">)(</span><span style=3D"color:#008">int</span><span style=3D"color:#660"=
>)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">->=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">auto<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">return</span><span style=3D"color:#000"> f</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#066">42</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">};</span><span style=3D"color:#000"> =C2=A0</span><span sty=
le=3D"color:#800">// never</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> bfive </span>=
<span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">[](</span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(*</span><span st=
yle=3D"color:#000">f</span><span style=3D"color:#660">)(</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#660">))</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color=
:#066">42</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000">=
=C2=A0</span><span style=3D"color:#800">// never</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">auto</span><span style=3D"col=
or:#000"> bsix </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">[](</span><span style=3D"colo=
r:#008">int</span><span style=3D"color:#000"> f</span><span style=3D"color:=
#660">(</span><span style=3D"color:#008">int</span><span style=3D"color:#66=
0">))</span><span style=3D"color:#000"> </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"> f</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#066">42</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">// C++11 (t=
akes a function pointer)</span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">auto</span><span style=3D"color:#000"> bseven </span><=
span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">[](</span><span style=3D"color:#008">int</span><span=
style=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#008">auto</span><span style=3D"color:#660">))</span><span styl=
e=3D"color:#000"> </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"> f</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#066">42</span><span style=3D"color:#660">);</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
> =C2=A0</span><span style=3D"color:#800">// never</span></div></code></div=
><div><br></div></div><span class=3D""><div>=C2=A0<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex">=C2=A0 =C2=A0 void f(auto(auto)); =C2=A0// equival=
ent to #1
<br></blockquote><div><br></div></span><div>IMHO, this should be disallowed=
.. It deduces a function type for the parameter, and then "decays"=
that type to a function pointer, in the same way that parameters of array =
type "decay" to pointers. This was inherited from C, is super con=
fusing, and in an age of generic lambda functors really deserves to be put =
to bed.</div><div><br></div><div style=3D"background-color:rgb(250,250,250)=
;border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span s=
tyle=3D"color:#008">auto</span><span style=3D"color:#000"> f</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> ga</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#660">))</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> ga</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#080">"hello world"</span><span style=3D"color:#660">);</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span=
style=3D"color:#000"> g</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#008">auto</span><span style=3D"color:#000"> xa</span><span sty=
le=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"> puts</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">xa</span><span style=3D"colo=
r:#660">);</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">int</span><span style=3D"color:#000"> main</span><span style=3D"color:#66=
0">()</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">g</span><span style=3D"color:#660">);</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">}</span></div>=
</code></div><div><br></div><div>Today, even though it looks like <font fac=
e=3D"courier new, monospace">ga</font> and <font face=3D"courier new, monos=
pace">g</font> have the same type, they don't! <font face=3D"courier ne=
w, monospace">g</font> is a function <b><i>template</i></b>, and <font face=
=3D"courier new, monospace">ga</font> is a <b><i>pointer to a function of u=
nspecified type</i></b>.</div><div>The idiomatically correct signature for =
<font face=3D"courier new, monospace">f</font>=C2=A0IMHO would be</div><div=
><br></div><div style=3D"background-color:rgb(250,250,250);border:1px solid=
rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:#00=
0">=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">auto</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#660">*</span><span style=3D"color:#000">ga</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">retu=
rn</span><span style=3D"color:#000"> ga</span><span style=3D"color:#660">(<=
/span><span style=3D"color:#080">"hello world"</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"><br></span></div></code></di=
v><span class=3D""><div><br><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x">b) variadic auto
<br>=C2=A0 =C2=A0 Once an ellipsis is seen as part of the declarator, all c=
ontained
<br>auto placeholders get transformed into parameter packs.
<br>=C2=A0 =C2=A0 void f(auto (*...)(auto) -> std::tuple<auto, std::p=
air<auto, auto>...>);
<br>=C2=A0Note there are 4 deducible template parameter packs above.=C2=A0<=
br></blockquote><div><br></div></span><div>Do I understand correctly that t=
he above is exactly equivalent to</div><div><br></div><div style=3D"backgro=
und-color:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:brea=
k-word"><code><div><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span st=
yle=3D"color:#008">template</span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#008">class</span><span style=3D"color:#660">...</span><s=
pan style=3D"color:#000"> A</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">class</span><span s=
tyle=3D"color:#660">...</span><span style=3D"color:#000"> B</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D=
"color:#008">class</span><span style=3D"color:#660">...</span><span style=
=3D"color:#000"> C</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#660">...</span><span style=3D"color:#000"> D</span><span style=3D"col=
or:#660">></span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> f1</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">tuple</span><span =
style=3D"color:#660"><</span><span style=3D"color:#000">A</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">pair</span><span style=
=3D"color:#660"><</span><span style=3D"color:#000">B</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000">C</span><span style=3D"c=
olor:#660">>...></span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(*...</span><span style=3D"color:#000">args</span><span sty=
le=3D"color:#660">)(</span><span style=3D"color:#000">D</span><span style=
=3D"color:#660">));</span><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">void</span><span style=3D"color:#000"> f2=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">std</s=
pan><span style=3D"color:#660">::</span><span style=3D"color:#000">tuple</s=
pan><span style=3D"color:#660"><</span><font color=3D"#000000"><span sty=
le=3D"color:#008">auto</span></font><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span=
style=3D"color:#000">pair</span><span style=3D"color:#660"><</span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#660">,</span><span =
style=3D"color:#008">auto</span><span style=3D"color:#660">>...></spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">(*...</span=
><span style=3D"color:#000">args</span><span style=3D"color:#660">)(</span>=
<font color=3D"#000000"><span style=3D"color:#008">auto</span></font><span =
style=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div>=
</code></div><div><br></div><div>where <font face=3D"courier new, monospace=
">f1</font> uses C++11 syntax and <font face=3D"courier new, monospace">f2<=
/font> uses only "abbreviated template" syntax?</div><span class=
=3D""><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">c) multi abbre=
viated template declarations
<br>=C2=A0 =C2=A0void f(auto), g(auto);
<br>are allowed - the above declares two function templates.
<br></blockquote><div><br></div></span><div>That's not allowed for non-=
abbreviated templates, and again I don't see a use-case for it. What=
9;s a case where I would want to chain together function declarations like =
that? Again, that seems like cruft inherited from C that could easily be du=
mped at least for new syntax.</div><div>=C2=A0<br></div><div>You don't =
mention this as a pitfall, but looking at your test cases I observed that</=
div><div><br></div><div style=3D"background-color:rgb(250,250,250);border:1=
px solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"c=
olor:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span=
style=3D"color:#000"> foo </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#066">42</span><span st=
yle=3D"color:#660">;</span><span style=3D"color:#000"> =C2=A0</span><span s=
tyle=3D"color:#800">// foo is definitely an int</span><span style=3D"color:=
#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">void</span><span =
style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#008">auto</span><span style=3D"color:#000"> baz </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#066">42</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">// baz is NOT an i=
nt; it's of some deduced type.</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =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">// The initia=
lizer 42 is coerced to that type if necessary.</span></div></code></div><di=
v><br></div><div>Consider the following progression:</div><div><br></div><d=
iv style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,=
187);word-wrap:break-word"><code><div><span style=3D"color:#008">template</=
span><span style=3D"color:#660"><</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> X</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> Y</span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#008">int</span><span style=3D"color:#660">></span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> one</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">X x</span><span style=3D"color:#660">,</span><span s=
tyle=3D"color:#000"> Y y</span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#066">1</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> x</span><span style=3D"color:#660">+</span><span style=3D"color=
:#000">y</span><span style=3D"color:#660">;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"> =
=C2=A0</span><span style=3D"color:#800">// legal C++14</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">template</span><span sty=
le=3D"color:#660"><</span><span style=3D"color:#008">class</span><span s=
tyle=3D"color:#000"> X</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> Y</span><span style=3D"color:#660">></span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> two</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">X x</span><span style=3D"color:#660">,</span><span style=3D=
"color:#000"> Y y</span><span style=3D"color:#660">=3D</span><span style=3D=
"color:#066">1</span><span style=3D"color:#660">)</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">return</span><span style=3D"color:#00=
0"> x</span><span style=3D"color:#660">+</span><span style=3D"color:#000">y=
</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">};</span><span style=3D"color:#000"> =C2=A0</s=
pan><span style=3D"color:#800">// invalid, and rightly so</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> three </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">[](</span><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> x</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">auto</span><span style=3D"color:#000"> y</span><span style=3D"co=
lor:#660">=3D</span><span style=3D"color:#066">1</span><span style=3D"color=
:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ret=
urn</span><span style=3D"color:#000"> x</span><span style=3D"color:#660">+<=
/span><span style=3D"color:#000">y</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><sp=
an style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">// invalid=
, but I claim it has an obvious meaning that should be standardized</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> four</span><span style=3D"color:#660">(</span><=
span style=3D"color:#008">auto</span><span style=3D"color:#000"> x</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">auto</span><span style=3D"color:#000"> y</span><span st=
yle=3D"color:#660">=3D</span><span style=3D"color:#066">1</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> x</span><span style=3D"color=
:#660">+</span><span style=3D"color:#000">y</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">};<=
/span><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">/=
/ invalid?? with your patch, but I claim it has an obvious meaning</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#008">int</span><s=
pan style=3D"color:#000"> main</span><span style=3D"color:#660">()</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"> one</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#066">1</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"> two</span><span style=3D"color:#660">(</span><span style=
=3D"color:#066">2</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"> three</span><span style=3D"color:#660">(</span><span style=3D"=
color:#066">3</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"> four</span><span style=3D"color:#660">(</span><span style=3D"color=
:#066">4</span><span style=3D"color:#660">);</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r></span></div></code></div><div><br>I know this has been a massive and sca=
ttered array of potshots, but I hope you find some of it interesting and/or=
useful. :)</div><span class=3D"HOEnZb"><font color=3D"#888888"><div><br></=
div><div>=E2=80=93Arthur</div></font></span></div></blockquote></div><br></=
div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01494d54626b8005107a3778--
.
Author: Zhihao Yuan <zy@miator.net>
Date: Thu, 5 Mar 2015 13:57:57 -0500
Raw View
On Wed, Mar 4, 2015 at 12:59 PM, 'Geoffrey Romer' via ISO C++ Standard
- Future Proposals <std-proposals@isocpp.org> wrote:
>
> I find enhanced auto
> deduction very appealing (for reasons that others on this thread have
> elaborated), but am actively uninterested in the abbreviated template
> syntax. It seems to me to offer only a modest improvement in brevity, and
> pays for it with a very substantial reduction in readability. That
> compromise may be appropriate for lambdas, because brevity is particularly
> important inside a single expression, but it seems far less justifiable in
> the case of ordinary functions.
I objected the use of `auto` in generic lambda.
But for now, for "consistency", I think the connection
between
auto f(auto, auto) { ... }
and
auto f = [](auto, auto) { ... }
is desired.
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://bit.ly/blog4bsd
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.