Topic: An implementation of enhanced auto deduction and


Author: Faisal Vali <faisalv@gmail.com>
Date: Tue, 3 Mar 2015 20:39:47 -0600
Raw View
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 .

The last line of the README file tells you the subversion revision of
LLVM to use.

For examples of test cases that successfully compile, please refer to:
 -- https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-auto-vars-generalized.cpp
 -- https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-abbreviated-templates.cpp

I would certainly appreciate the feedback!

1) Enhanced-Auto Deduction:

 pair<auto...> f() { return make_pair([] { }, [] { }); }
 vector<auto> v = vector<int>();

2) Abbreviated Template Syntax:
void f(auto) <=> template<class T> void f(T);


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.
    void f(auto(auto));  // equivalent to #1
    void f(auto (auto) -> auto); // equivalent to #2
                                               // the trailing return type auto
                                               // identifies a
template parameter
    template<class R> void f(R(auto); // equivalent to #1
    template<class P> void f(auto(P)); // equivalent to #2

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.

c) multi abbreviated template declarations
   void f(auto), g(auto);
are allowed - the above declares two function templates.

d) template aliases desugar their types *after* each auto has been
identified as a placeholder (and so must be deduced)

    template<class T> using Int = int;
    Int<auto> i = 3; // Is an error, auto must be deducible.

e) generic lambda's as default arguments work with abbreviated template syntax:
  void f(int (*)(int) = [](auto a) { return a; }, auto b = decltype(b){});
  f<float*>(); // OK

f) variable templates and enhanced auto deduction interact as expected:
    template<class T> pair<auto...> (*vfp)(auto...) = [](T t1, T* t2)
{ return make_pair(t1, t2); };

Thanks!
Faisal Vali

--

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

.


Author: Gabriel Dos Reis <gdr@microsoft.com>
Date: Wed, 4 Mar 2015 03:45:01 +0000
Raw View
Should we declare "auto f(auto) -> auto" an excess in sophism?

-- Gaby


> On Mar 3, 2015, at 6:39 PM, Faisal Vali <faisalv@gmail.com> 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 .
>
> The last line of the README file tells you the subversion revision of
> LLVM to use.
>
> For examples of test cases that successfully compile, please refer to:
> -- https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-auto-vars-generalized.cpp
> -- https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-abbreviated-templates.cpp
>
> I would certainly appreciate the feedback!
>
> 1) Enhanced-Auto Deduction:
>
> pair<auto...> f() { return make_pair([] { }, [] { }); }
> vector<auto> v = vector<int>();
>
> 2) Abbreviated Template Syntax:
> void f(auto) <=> template<class T> void f(T);
>
>
> 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.
>    void f(auto(auto));  // equivalent to #1
>    void f(auto (auto) -> auto); // equivalent to #2
>                                               // the trailing return type auto
>                                               // identifies a
> template parameter
>    template<class R> void f(R(auto); // equivalent to #1
>    template<class P> void f(auto(P)); // equivalent to #2
>
> 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.
>
> c) multi abbreviated template declarations
>   void f(auto), g(auto);
> are allowed - the above declares two function templates.
>
> d) template aliases desugar their types *after* each auto has been
> identified as a placeholder (and so must be deduced)
>
>    template<class T> using Int = int;
>    Int<auto> i = 3; // Is an error, auto must be deducible.
>
> e) generic lambda's as default arguments work with abbreviated template syntax:
>  void f(int (*)(int) = [](auto a) { return a; }, auto b = decltype(b){});
>  f<float*>(); // OK
>
> f) variable templates and enhanced auto deduction interact as expected:
>    template<class T> pair<auto...> (*vfp)(auto...) = [](T t1, T* t2)
> { return make_pair(t1, t2); };
>
> Thanks!
> Faisal Vali
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

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

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 3 Mar 2015 21:36:02 -0800 (PST)
Raw View
------=_Part_1541_18154460.1425447362472
Content-Type: multipart/alternative;
 boundary="----=_Part_1542_1102375481.1425447362472"

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

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=20
> time or the interest to play with a patched up Clang that implements=20
> enhanced auto deduction & abbreviated template syntax from the=20
> concepts ts, here it is:=20
>
> https://github.com/faisalv/clang/tree/enhanced-auto-c%2B%2B1z .=20
>

That's *very very cool* =E2=80=94 at least the "abbreviated template syntax=
" half!=20
;)  Is it possible for you to separate out the "abbreviated template=20
syntax" feature from the "enhanced auto detection" feature, into two=20
separate patches that could be looked at and/or adopted individually?
=20
Now that we have generic lambdas (in C++14), I'm looking forward to having=
=20
"generic functions" (i.e., abbreviated template syntax) sooner rather than=
=20
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:=20
>
>  pair<auto...> f() { return make_pair([] { }, [] { }); }=20
>  vector<auto> v =3D vector<int>();=20
>

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=20
"enhanced deduction" for type aliases. I don't like the asymmetry this=20
creates between "class types" and "typedef types".  Here are a collection=
=20
of "enhanced" cases where deduction fails (in some cases, MUST fail).=20

    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,=
=20
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=20
use-case. And I'm not sure how it could.


> 2) Abbreviated Template Syntax:=20
> void f(auto) <=3D> template<class T> void f(T);
>

THIS is the very very awesome part. I am super excited about this feature=
=20
finally coming to a compiler near me!

A few, perhaps not so obvious or interesting, technicalities:=20
>
> a)  The equivalence of templates when it comes to trailing return=20
> types in function pointer parameters is based on the order of the=20
> 'auto' that signifies a placeholder, not just the appearance of an=20
> auto in the declaration-specifier of a parameter:=20
>
>     template<class R, class P> void f( R(P) );  // #1=20
>     template<class P, class R> void f(  R(P) );  // #2 (order of=20
> templ-params flipped)=20
>
>     template<class R, class P> void f( auto (P)->R); // equivalent to=20
> #1, not abbreviated.=20
>

How many of these weirdnesses vanish if you get rid of "enhanced auto=20
deduction"?
Clang 3.7.0 doesn't currently allow trailing return types on C++14 generic=
=20
lambda parameters, which IMHO is a feature (in that allowing them leads to=
=20
the grotesqueries you mention) but I'm pretty sure from the Standard's POV=
=20
is a bug. (Contrariwise, I think GCC 5.0.0 is *too* permissive. But in=20
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 function=
=20
pointer)
auto bseven =3D [](int f(auto)) { return f(42); };  // never

=20

>     void f(auto(auto));  // equivalent to #1=20
>

IMHO, this should be disallowed. It deduces a function type for the=20
parameter, and then "decays" that type to a function pointer, in the same=
=20
way that parameters of array type "decay" to pointers. This was inherited=
=20
from C, is super confusing, and in an age of generic lambda functors really=
=20
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=
=20
is a function *template*, and ga is a *pointer to a function of unspecified=
=20
type*.
The idiomatically correct signature for f IMHO would be

    auto f(auto *ga) { return ga("hello world"); }


b) variadic auto=20
>     Once an ellipsis is seen as part of the declarator, all contained=20
> auto placeholders get transformed into parameter packs.=20
>     void f(auto (*...)(auto) -> std::tuple<auto, std::pair<auto,=20
> auto>...>);=20
>  Note there are 4 deducible template parameter packs above.=20
>

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=20
>    void f(auto), g(auto);=20
> are allowed - the above declares two function templates.=20
>

That's not allowed for non-abbreviated templates, and again I don't see a=
=20
use-case for it. What's a case where I would want to chain together=20
function declarations like that? Again, that seems like cruft inherited=20
from C that could easily be dumped at least for new syntax.
=20
You don't mention this as a pitfall, but looking at your test cases I=20
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 deduced=
=20
type.
                              // The initializer 42 is coerced to that type=
=20
if necessary.

Consider the following progression:

template<class X, class Y=3Dint> auto one(X x, Y y=3D1) { return x+y; };  /=
/=20
legal C++14
template<class X, class Y> auto two(X x, Y y=3D1) { return x+y; };  //=20
invalid, and rightly so
auto three =3D [](auto x, auto y=3D1) { return x+y; };  // invalid, but I c=
laim=20
it has an obvious meaning that should be standardized
auto four(auto x, auto y=3D1) { return x+y; };  // invalid?? with your patc=
h,=20
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 hope=
=20
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/.

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

<div dir=3D"ltr">On Tuesday, March 3, 2015 at 6:39:49 PM UTC-8, faisalv wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">In the hopes of soliciting =
constructive feedback, if anyone has the
<br>time or the interest to play with a patched up Clang that implements
<br>enhanced auto deduction &amp; 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" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Ftree%2Fe=
nhanced-auto-c%252B%252B1z\46sa\75D\46sntz\0751\46usg\75AFQjCNF797qFdVpxoz9=
OgazeR_JgUA4ESA';return true;" onclick=3D"this.href=3D'https://www.google.c=
om/url?q\75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Ftree%2Fenhanced-aut=
o-c%252B%252B1z\46sa\75D\46sntz\0751\46usg\75AFQjCNF797qFdVpxoz9OgazeR_JgUA=
4ESA';return true;">https://github.com/faisalv/<wbr>clang/tree/enhanced-aut=
o-c%2B%<wbr>2B1z</a> .
<br></blockquote><div><br></div><div>That's <b>very very cool</b> =E2=80=94=
 at least the "abbreviated template syntax" half! ;) &nbsp;Is it possible f=
or you to separate out the "abbreviated template syntax" feature from the "=
enhanced auto detection" feature, into two separate patches that could be l=
ooked at and/or adopted individually?</div><div>&nbsp;</div><div>Now that w=
e have generic lambdas (in C++14), I'm looking forward to having "generic f=
unctions" (i.e., abbreviated template syntax) sooner rather than later.</di=
v><div><br></div><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// C++14: Create a lambda o=
bject with a template member operator()</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">auto</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><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">[](</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// C++1z: Create a template function directly</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &=
nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</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"> y</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</sp=
an></div></code></div><div><div><br></div></div><div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;">1) Enhanced-Auto Deduction:
<br>
<br>&nbsp;pair&lt;auto...&gt; f() { return make_pair([] { }, [] { }); }
<br>&nbsp;vector&lt;auto&gt; v =3D vector&lt;int&gt;();
<br></blockquote><div><br></div><div>I don't see the use-case for this feat=
ure. Why would I write</div><div><br></div><div><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
&nbsp; &nbsp; vector</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">&lt;auto&gt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> v </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v=
ector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;i=
nt&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span></div></code></div></div><div><br></div><div>when it's less typing an=
d less noise to just write</div><div><br></div><div><div class=3D"prettypri=
nt" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> v </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> vector</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span></di=
v></code></div></div><div><br></div><div>? Also, as you noted in technicali=
ty (d), it's impossible to support "enhanced deduction" for type aliases. I=
 don't like the asymmetry this creates between "class types" and "typedef t=
ypes". &nbsp;Here are a collection of "enhanced" cases where deduction fail=
s (in some cases, MUST fail).&nbsp;</div><div><br></div><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">using</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> identity1 </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; &nbsp; identity1</span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">&lt;auto&gt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> id1 </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: #066;" class=
=3D"styled-by-prettify">42</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"style=
d-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-pre=
ttify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> identity2 </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: #00=
8;" class=3D"styled-by-prettify">using</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> type </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp;=
 identity2</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&lt;auto&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">type i=
d2 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #066;" class=3D"styled-by-prettify">42</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><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"> T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> int3 </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">using</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> type </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; &nbsp; int3</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify">&lt;auto&gt;</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">type id3 </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">42</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span=
 style=3D"color: #080;" class=3D"styled-by-prettify">&lt;class&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">using</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> int4 </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: #008;" class=
=3D"styled-by-prettify">int</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>&nbsp; &nbsp; int4</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">&lt;auto&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> id4 </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">42</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an></div></code></div><div><br></div><div>I'm mostly concerned with the fac=
t that you're making identity1&lt;auto&gt; fail, while vector&lt;auto&gt; s=
ucceeds.</div><div><br></div><div>Here's a use-case I could maybe get behin=
d:</div><div><br></div><div><div class=3D"prettyprint" style=3D"background-=
color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap:=
 break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; vector=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;auto&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> vec </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">1</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: #066;" class=3D"styled-by-prettify=
">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"co=
lor: #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"> &nbsp;</span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">// creates a vector of int</span></div></code></div></=
div><div><br></div><div>except that (correct me if I'm wrong) your patch do=
esn't support that use-case. And I'm not sure how it could.</div><div><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>2) Abbreviated Template Syntax:
<br>void f(auto) &lt;=3D&gt; template&lt;class T&gt; void f(T);<br></blockq=
uote><div><br></div><div>THIS is the very very awesome part. I am super exc=
ited about this feature finally coming to a compiler near me!</div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">A few, perhaps not so o=
bvious or interesting, technicalities:
<br>
<br>a) &nbsp;The 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>&nbsp; &nbsp; template&lt;class R, class P&gt; void f( R(P) ); &nbsp;//=
 #1
<br>&nbsp; &nbsp; template&lt;class P, class R&gt; void f( &nbsp;R(P) ); &n=
bsp;// #2 (order of
<br>templ-params flipped)
<br>
<br>&nbsp; &nbsp; template&lt;class R, class P&gt; void f( auto (P)-&gt;R);=
 // equivalent to
<br>#1, not abbreviated.
<br></blockquote><div><br></div><div>How many of these weirdnesses vanish i=
f you get rid of "enhanced auto deduction"?</div><div>Clang 3.7.0 doesn't c=
urrently allow trailing return types on C++14 generic lambda parameters, wh=
ich IMHO is a feature (in that allowing them leads to the grotesqueries you=
 mention) but I'm pretty sure from the Standard's POV is a bug. (Contrariwi=
se, I think GCC 5.0.0 is *too* permissive. But in neither case am I sure ex=
actly what's allowed by the Standard.)</div><div><br></div><div><a href=3D"=
http://melpon.org/wandbox/permlink/QMQXHNsBmwVJbxM0">http://melpon.org/wand=
box/permlink/QMQXHNsBmwVJbxM0<br></a></div><div><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word;"><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"> one</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">int</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">f</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)(</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">42</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"> &nbsp;<=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// C++03</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> two</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">auto</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">f</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">-&gt;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #066;" class=3D"styled-by-prettify">42</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// C++11</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> three</sp=
an><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: #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">f</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)(</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">42</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"> &nbsp;<=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// never</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> four</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: #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-b=
y-prettify">f</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">42</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">// never</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fi=
ve</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(*</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)(</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">))</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;"=
 class=3D"styled-by-prettify">42</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">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> &=
nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// ne=
ver</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> six</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">))</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;"=
 class=3D"styled-by-prettify">42</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">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> &=
nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// C+=
+03 (takes a function pointer)</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-pre=
ttify"> seven</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><spa=
n 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"co=
lor: #660;" class=3D"styled-by-prettify">))</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #066;" class=3D"styled-by-prettify">42</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// never</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> bone </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: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">))</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">42</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-pre=
ttify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// C++11</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"> btwo </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</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"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(*</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">f</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #066;" class=3D"styled-by-prettify">42</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;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// never</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> bthree </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: #008;" class=3D"styled-by-prettify">auto</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">f</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)(</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">42</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"> &nbsp;=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// C++14</=
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 s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> bfour </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">[](</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</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">-&gt;</span><span style=3D"color: #000;"=
 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"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">42</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 &nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
never</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"> bfive </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">[](</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</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-pr=
ettify">f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">42</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// never</span><span style=3D"c=
olor: #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"> bsix </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">[](</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">int</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: #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-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">42</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> &nbsp;</span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// C++11 (takes a function pointer)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> bseven </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">[](</span><span style=3D"color: #008;" class=3D"st=
yled-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-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
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: #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">return</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">42</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// never</span></div></code>=
</div><div><br></div></div><div>&nbsp;<br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;">&nbsp; &nbsp; void f(auto(auto)); &nbsp;// equivalent to =
#1
<br></blockquote><div><br></div><div>IMHO, this should be disallowed. It de=
duces a function type for the parameter, and then "decays" that type to a f=
unction pointer, in the same way that parameters of array type "decay" to p=
ointers. This was inherited from C, is super confusing, and in an age of ge=
neric lambda functors really deserves to be put to bed.</div><div><br></div=
><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); =
border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> ga</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> ga</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
"hello world"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</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"><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"> g</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> xa</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> puts</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">xa</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> main</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">g</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-pretti=
fy">}</span></div></code></div><div><br></div><div>Today, even though it lo=
oks like <font face=3D"courier new, monospace">ga</font> and <font face=3D"=
courier new, monospace">g</font> have the same type, they don't! <font face=
=3D"courier new, 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 unspecified type</i></b>.</div><div>The idiomatically correct =
signature for <font face=3D"courier new, monospace">f</font>&nbsp;IMHO woul=
d be</div><div><br></div><div class=3D"prettyprint" style=3D"background-col=
or: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: br=
eak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</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">ga</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> ga</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">"hello world"</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">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span></div></code></div><div><br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">b) variadic auto
<br>&nbsp; &nbsp; Once an ellipsis is seen as part of the declarator, all c=
ontained
<br>auto placeholders get transformed into parameter packs.
<br>&nbsp; &nbsp; void f(auto (*...)(auto) -&gt; std::tuple&lt;auto, std::p=
air&lt;auto, auto&gt;...&gt;);
<br>&nbsp;Note there are 4 deducible template parameter packs above.&nbsp;<=
br></blockquote><div><br></div><div>Do I understand correctly that the abov=
e is exactly equivalent to</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">&=
nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">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"color: #660;" class=3D"styled-by-prettify">...</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> A</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">class</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> B</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> C</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">class</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> D</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> f1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">A</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">pair</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">B<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">C</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;...&gt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(*...</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">args</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)(</span><span style=3D"color: #000;" 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-pretti=
fy"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> f2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><font color=3D"=
#000000"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</sp=
an></font><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">pair</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</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">&gt;...&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(*...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)(</s=
pan><font color=3D"#000000"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">auto</span></font><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><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"couri=
er new, monospace">f2</font> uses only "abbreviated template" syntax?</div>=
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">c) multi abbrev=
iated template declarations
<br>&nbsp; &nbsp;void f(auto), g(auto);
<br>are allowed - the above declares two function templates.
<br></blockquote><div><br></div><div>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 s=
eems like cruft inherited from C that could easily be dumped at least for n=
ew syntax.</div><div>&nbsp;<br></div><div>You don't mention this as a pitfa=
ll, but looking at your test cases I observed that</div><div><br></div><div=
 class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); borde=
r: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">&nbsp; &nbsp; </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">42</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// foo is definit=
ely an int</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">void</span><span style=3D"color: #000;" 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">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> baz </span><span s=
tyle=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: #=
066;" class=3D"styled-by-prettify">42</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styl=
ed-by-prettify">// baz is NOT an int; it's of some deduced type.</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; </span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// The initializer 42 is coerced to that type if necessary.</span></div>=
</code></div><div><br></div><div>Consider the following progression:</div><=
div><br></div><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" c=
lass=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: #008;" class=3D"styled-by-prettify=
">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> Y<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> one</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">X x</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
Y y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify">y</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> &nbsp;</span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// legal C++14</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" c=
lass=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"s=
tyled-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: #008;" class=3D"styled-by-prettify">class</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> Y</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> two</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">X x</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> Y y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify">y=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> &nbsp;</span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">// invalid, and rightly so</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"> three </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: #008;" class=3D"sty=
led-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">y</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled-=
by-prettify">// invalid, but I claim it has an obvious meaning that should =
be standardized</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> four</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</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"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> y</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D</span><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</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-b=
y-prettify">y</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</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 =
style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">// invalid?? with your pat=
ch, but I claim it has an obvious meaning</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"> main</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> one</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> two</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> t=
hree</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> four</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">4</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span></div></code></div><div><br>I know this has been a massive and scatter=
ed array of potshots, but I hope you find some of it interesting and/or use=
ful. :)</div><div><br></div><div>=E2=80=93Arthur</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1542_1102375481.1425447362472--
------=_Part_1541_18154460.1425447362472--

.


Author: Faisal Vali <faisalv@gmail.com>
Date: Wed, 4 Mar 2015 06:45:02 -0600
Raw View
On Tue, Mar 3, 2015 at 11: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 syntax=
" half! ;)
> 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>();
>

I generally agree with the above statement - but there are some who
have argued that it can improve readability - and I see their point
too.


> ? 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> fai=
l,
> while vector<auto> succeeds.

Sorry, I was unclear - identity1<auto> id1 =3D 42 is the only one of
your examples that works.  What does not work is: if you invent a
template parameter for each placeholder in your declaration - but
while doing template argument deduction thru a function call, if any
template parameters are left undeduced - that's an error (even if the
alias does not use the template parameter after desugarring).
Consider:
  template<class T> void f(int4<T> id4);
  f(42); // Error.


>
> 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.
>

No - since template argument deduction for function calls does not support =
that.

>>
>> 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!

Hah - our gcc friends have had this for ages :) - I've submitted a
patch for clang's review - but if history is any indication - the
review cycles (my latencies included) can take months.


>
>> 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"?

None - this has nothing to do with initializer deduction - only
trailing return type syntax.

> 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.)
>

No one is sure (except for maybe 10 or so kingsmen* that round table
it ~twice a year) exactly what's allowed by the standard ;)
(*) gender neutrality invoked

> 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.

I hear you - but it is easier to write test cases without the extra
syntax to denote a ptr or ref.

>
> 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=
?
>

Yes.


>> 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 funct=
ion
> declarations like that? Again, that seems like cruft inherited from C tha=
t
> could easily be dumped at least for new syntax.
>

I don't think I care much either way - but I don't think this
forbidden by the TS.

> 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 ty=
pe
> if necessary.

Yes - I can see the potential for confusion - but perhaps if you
mentally replace an 'auto' in a function declaration with a template
type parameter, and in an initializer deduction with a function call
with the initializer, perhaps the confusion can be minimized - but I
agree, it is unfortunate that such asymmetry exists.

>
> 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 pa=
tch,
> 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

I certainly did - Thanks!

--=20

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

.


Author: Scott Prager <splinterofchaos@gmail.com>
Date: Wed, 4 Mar 2015 08:52:50 -0800 (PST)
Raw View
------=_Part_337_334394783.1425487970241
Content-Type: multipart/alternative;
 boundary="----=_Part_338_208413682.1425487970241"

------=_Part_338_208413682.1425487970241
Content-Type: text/plain; charset=UTF-8

Great stuff! No more writing *is_tuple* and *is_pair* functions to get
SFINAE overloading. Although, a few things get me...

(sorry, the code formatter isn't working for me right now)

/// TEST
*template<class X>*
*void check(auto&& x) {*
* static_assert(std::is_same<decltype(x), X&&>::value);*
*}*

*template<class X>*
*void check_copy(auto x) {*
* static_assert(std::is_same<decltype(x), X>::value);*
*}*

*//...*

*int one;*
*const int cone = 1;*
*check<int>(1);*
*check<int&>(one);*
*check<const int&>(cone);*

*check_copy<int>(1);*
*check_copy<int>(one);*
*check_copy<int>(cone);*
/// END TEST

So, this check shows that when used as a function parameter,
auto behaves very similarly to auto-initializing a variable.

/// TEST
*std::pair<auto...> p = std::pair<int, int>(1,1);*
*std::pair<auto...> q = std::pair<int&, int&>(one,one);*
*std::pair<auto...> r = std::pair<int&&, int&&>(1,1);*

*template<class X> using P = std::pair<X,X>&;*
*check<P<int>>(p);*
*check<P<int&>>(q);*
*check<P<int&&>>(r);*
/// END TEST

This should that *auto* as a template parameter works consistently in
that *tuple<T>* would bind to a reference or rvlaue as well. I tested
*auto& *and *auto&&* in this context as well, and they match against
references and rvalues like template parameters.

*void check_pair(std::pair<auto&&, auto&&>) { static_assert(true); }*

Particularly, this will only work if passed a *pair<X&&, Y&&> *with
*std::move*...
While it's entirely consistent with the rest of the language, it just
seems odd that *auto* in one instance decays the type and in another
acts like *decltype(auto)*. Not a complaint, just an observation.


On Tuesday, March 3, 2015 at 9:39:49 PM UTC-5, 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 .
>
> The last line of the README file tells you the subversion revision of
> LLVM to use.
>
> For examples of test cases that successfully compile, please refer to:
>  --
> https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-auto-vars-generalized.cpp
>  --
> https://github.com/faisalv/clang/blob/enhanced-auto-c%2B%2B1z/test/CXX/auto/cxx1z-abbreviated-templates.cpp
>
> I would certainly appreciate the feedback!
>
> 1) Enhanced-Auto Deduction:
>
>  pair<auto...> f() { return make_pair([] { }, [] { }); }
>  vector<auto> v = vector<int>();
>
> 2) Abbreviated Template Syntax:
> void f(auto) <=> template<class T> void f(T);
>
>
> 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.
>     void f(auto(auto));  // equivalent to #1
>     void f(auto (auto) -> auto); // equivalent to #2
>                                                // the trailing return type
> auto
>                                                // identifies a
> template parameter
>     template<class R> void f(R(auto); // equivalent to #1
>     template<class P> void f(auto(P)); // equivalent to #2
>
> 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.
>
> c) multi abbreviated template declarations
>    void f(auto), g(auto);
> are allowed - the above declares two function templates.
>
> d) template aliases desugar their types *after* each auto has been
> identified as a placeholder (and so must be deduced)
>
>     template<class T> using Int = int;
>     Int<auto> i = 3; // Is an error, auto must be deducible.
>
> e) generic lambda's as default arguments work with abbreviated template
> syntax:
>   void f(int (*)(int) = [](auto a) { return a; }, auto b = decltype(b){});
>   f<float*>(); // OK
>
> f) variable templates and enhanced auto deduction interact as expected:
>     template<class T> pair<auto...> (*vfp)(auto...) = [](T t1, T* t2)
> { return make_pair(t1, t2); };
>
> Thanks!
> Faisal Vali
>

--

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

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

<div dir=3D"ltr">Great stuff! No more writing <i>is_tuple</i>&nbsp;and <i>i=
s_pair</i>&nbsp;functions to get<div>SFINAE overloading. Although, a few th=
ings get me...</div><div><br></div><div>(sorry, the code formatter isn't wo=
rking for me right now)</div><div><br></div><div>/// TEST</div><div><div><i=
>template&lt;class X&gt;</i></div><div><i>void check(auto&amp;&amp; x) {</i=
></div><div><i><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </=
span>static_assert(std::is_same&lt;decltype(x), X&amp;&amp;&gt;::value);</i=
></div><div><i>}</i></div><div><i><br></i></div><div><i>template&lt;class X=
&gt;</i></div><div><i>void check_copy(auto x) {</i></div><div><i><span clas=
s=3D"Apple-tab-span" style=3D"white-space:pre"> </span>static_assert(std::i=
s_same&lt;decltype(x), X&gt;::value);</i></div><div><i>}</i></div><div><i><=
br></i></div><div><i>//...</i></div><div><i><br></i></div><div><div><i>int =
one;</i></div><div><i>const int cone =3D 1;</i></div><div><i>check&lt;int&g=
t;(1);</i></div><div><i>check&lt;int&amp;&gt;(one);</i></div><div><i>check&=
lt;const int&amp;&gt;(cone);</i></div><div><i><br></i></div><div><i>check_c=
opy&lt;int&gt;(1);</i></div><div><i>check_copy&lt;int&gt;(one);</i></div><d=
iv><i>check_copy&lt;int&gt;(cone);</i></div><div>/// END TEST</div></div><d=
iv><br></div><div>So, this check shows that when used as a function paramet=
er,</div><div>auto behaves very similarly to auto-initializing a variable.<=
/div><div><br></div><div>/// TEST</div><div><div><div><i>std::pair&lt;auto.=
...&gt; p =3D std::pair&lt;int, int&gt;(1,1);</i></div><div><i>std::pair&lt;=
auto...&gt; q =3D std::pair&lt;int&amp;, int&amp;&gt;(one,one);</i></div><d=
iv><i>std::pair&lt;auto...&gt; r =3D std::pair&lt;int&amp;&amp;, int&amp;&a=
mp;&gt;(1,1);</i></div><div><i><br></i></div><div><i>template&lt;class X&gt=
; using P =3D std::pair&lt;X,X&gt;&amp;;</i></div><div><i>check&lt;P&lt;int=
&gt;&gt;(p);</i></div><div><i>check&lt;P&lt;int&amp;&gt;&gt;(q);</i></div><=
div><i>check&lt;P&lt;int&amp;&amp;&gt;&gt;(r);</i></div></div><div>/// END =
TEST</div></div><div><br></div><div>This should that <i>auto</i>&nbsp;as a =
template parameter works consistently in</div><div>that <i>tuple&lt;T&gt;</=
i>&nbsp;would bind to a reference or rvlaue as well. I tested</div><div><i>=
auto&amp; </i>and <i>auto&amp;&amp;</i>&nbsp;in this context as well, and t=
hey match against</div><div>references and rvalues like template parameters=
..</div><div><br></div><div><div><i>void check_pair(std::pair&lt;auto&amp;&a=
mp;, auto&amp;&amp;&gt;) { static_assert(true); }</i></div></div><div><br><=
/div><div>Particularly, this will only work if passed a <i>pair&lt;X&amp;&a=
mp;, Y&amp;&amp;&gt; </i>with <i>std::move</i>...</div><div>While it's enti=
rely consistent with the rest of the language, it just</div><div>seems odd =
that <i>auto</i>&nbsp;in one instance decays the type and in another</div><=
div>acts like <i>decltype(auto)</i>. Not a complaint, just an observation.<=
/div><div><br></div><br>On Tuesday, March 3, 2015 at 9:39:49 PM UTC-5, fais=
alv wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">In the hopes of soli=
citing constructive feedback, if anyone has the
<br>time or the interest to play with a patched up Clang that implements
<br>enhanced auto deduction &amp; 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" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Ftree%2Fe=
nhanced-auto-c%252B%252B1z\46sa\75D\46sntz\0751\46usg\75AFQjCNF797qFdVpxoz9=
OgazeR_JgUA4ESA';return true;" onclick=3D"this.href=3D'https://www.google.c=
om/url?q\75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Ftree%2Fenhanced-aut=
o-c%252B%252B1z\46sa\75D\46sntz\0751\46usg\75AFQjCNF797qFdVpxoz9OgazeR_JgUA=
4ESA';return true;">https://github.com/faisalv/<wbr>clang/tree/enhanced-aut=
o-c%2B%<wbr>2B1z</a> .
<br>
<br>The last line of the README file tells you the subversion revision of
<br>LLVM to use.
<br>
<br>For examples of test cases that successfully compile, please refer to:
<br>&nbsp;-- <a href=3D"https://github.com/faisalv/clang/blob/enhanced-auto=
-c%2B%2B1z/test/CXX/auto/cxx1z-auto-vars-generalized.cpp" target=3D"_blank"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\=
75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Fblob%2Fenhanced-auto-c%252B%=
252B1z%2Ftest%2FCXX%2Fauto%2Fcxx1z-auto-vars-generalized.cpp\46sa\75D\46snt=
z\0751\46usg\75AFQjCNHBhcz2hwtgv4D3zfU62V7DnwgxMg';return true;" onclick=3D=
"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Ffai=
salv%2Fclang%2Fblob%2Fenhanced-auto-c%252B%252B1z%2Ftest%2FCXX%2Fauto%2Fcxx=
1z-auto-vars-generalized.cpp\46sa\75D\46sntz\0751\46usg\75AFQjCNHBhcz2hwtgv=
4D3zfU62V7DnwgxMg';return true;">https://github.com/faisalv/<wbr>clang/blob=
/enhanced-auto-c%2B%<wbr>2B1z/test/CXX/auto/cxx1z-auto-<wbr>vars-generalize=
d.cpp</a>
<br>&nbsp;-- <a href=3D"https://github.com/faisalv/clang/blob/enhanced-auto=
-c%2B%2B1z/test/CXX/auto/cxx1z-abbreviated-templates.cpp" target=3D"_blank"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\=
75https%3A%2F%2Fgithub.com%2Ffaisalv%2Fclang%2Fblob%2Fenhanced-auto-c%252B%=
252B1z%2Ftest%2FCXX%2Fauto%2Fcxx1z-abbreviated-templates.cpp\46sa\75D\46snt=
z\0751\46usg\75AFQjCNEuB7QcHoYCbeatC5gyJAMXDpbXWQ';return true;" onclick=3D=
"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Ffai=
salv%2Fclang%2Fblob%2Fenhanced-auto-c%252B%252B1z%2Ftest%2FCXX%2Fauto%2Fcxx=
1z-abbreviated-templates.cpp\46sa\75D\46sntz\0751\46usg\75AFQjCNEuB7QcHoYCb=
eatC5gyJAMXDpbXWQ';return true;">https://github.com/faisalv/<wbr>clang/blob=
/enhanced-auto-c%2B%<wbr>2B1z/test/CXX/auto/cxx1z-<wbr>abbreviated-template=
s.cpp</a>
<br>
<br>I would certainly appreciate the feedback!
<br>
<br>1) Enhanced-Auto Deduction:
<br>
<br>&nbsp;pair&lt;auto...&gt; f() { return make_pair([] { }, [] { }); }
<br>&nbsp;vector&lt;auto&gt; v =3D vector&lt;int&gt;();
<br>
<br>2) Abbreviated Template Syntax:
<br>void f(auto) &lt;=3D&gt; template&lt;class T&gt; void f(T);
<br>
<br>
<br>A few, perhaps not so obvious or interesting, technicalities:
<br>
<br>a) &nbsp;The 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>&nbsp; &nbsp; template&lt;class R, class P&gt; void f( R(P) ); &nbsp;//=
 #1
<br>&nbsp; &nbsp; template&lt;class P, class R&gt; void f( &nbsp;R(P) ); &n=
bsp;// #2 (order of
<br>templ-params flipped)
<br>
<br>&nbsp; &nbsp; template&lt;class R, class P&gt; void f( auto (P)-&gt;R);=
 // equivalent to
<br>#1, not abbreviated.
<br>&nbsp; &nbsp; void f(auto(auto)); &nbsp;// equivalent to #1
<br>&nbsp; &nbsp; void f(auto (auto) -&gt; auto); // equivalent to #2
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp;// the trailing return type auto
<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp;// identifies a
<br>template parameter
<br>&nbsp; &nbsp; template&lt;class R&gt; void f(R(auto); // equivalent to =
#1
<br>&nbsp; &nbsp; template&lt;class P&gt; void f(auto(P)); // equivalent to=
 #2
<br>
<br>b) variadic auto
<br>&nbsp; &nbsp; Once an ellipsis is seen as part of the declarator, all c=
ontained
<br>auto placeholders get transformed into parameter packs.
<br>&nbsp; &nbsp; void f(auto (*...)(auto) -&gt; std::tuple&lt;auto, std::p=
air&lt;auto, auto&gt;...&gt;);
<br>&nbsp;Note there are 4 deducible template parameter packs above.
<br>
<br>c) multi abbreviated template declarations
<br>&nbsp; &nbsp;void f(auto), g(auto);
<br>are allowed - the above declares two function templates.
<br>
<br>d) template aliases desugar their types *after* each auto has been
<br>identified as a placeholder (and so must be deduced)
<br>
<br>&nbsp; &nbsp; template&lt;class T&gt; using Int =3D int;
<br>&nbsp; &nbsp; Int&lt;auto&gt; i =3D 3; // Is an error, auto must be ded=
ucible.
<br>
<br>e) generic lambda's as default arguments work with abbreviated template=
 syntax:
<br>&nbsp; void f(int (*)(int) =3D [](auto a) { return a; }, auto b =3D dec=
ltype(b){});
<br>&nbsp; f&lt;float*&gt;(); // OK
<br>
<br>f) variable templates and enhanced auto deduction interact as expected:
<br>&nbsp; &nbsp; template&lt;class T&gt; pair&lt;auto...&gt; (*vfp)(auto..=
..) =3D [](T t1, T* t2)
<br>{ return make_pair(t1, t2); };
<br>
<br>Thanks!
<br>Faisal Vali
<br></blockquote></div></div>

<p></p>

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

------=_Part_338_208413682.1425487970241--
------=_Part_337_334394783.1425487970241--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 4 Mar 2015 09:14:12 -0800 (PST)
Raw View
------=_Part_6382_703121146.1425489252130
Content-Type: multipart/alternative;
 boundary="----=_Part_6383_1902075028.1425489252130"

------=_Part_6383_1902075028.1425489252130
Content-Type: text/plain; charset=UTF-8



On Wednesday, March 4, 2015 at 12:36:02 AM UTC-5, Arthur O'Dwyer wrote:
>
>
> I don't see the use-case for this feature. Why would I write
>
>     vector<auto> v = vector<int>();
>
> when it's less typing and less noise to just write
>
>     auto v = vector<int>();
>

The use case for this:

vector<int> v;

array_view<auto> av = v; //deduces to array_view<int>



--

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

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

<div dir=3D"ltr"><br><br>On Wednesday, March 4, 2015 at 12:36:02 AM UTC-5, =
Arthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br><div>I don't see the use-case for this feature. Why would I wr=
ite</div><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><div><span =
style=3D"color:#000">&nbsp; &nbsp; vector</span><span style=3D"color:#080">=
&lt;auto&gt;</span><span style=3D"color:#000"> v </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> vector</span><span style=3D"c=
olor:#080">&lt;int&gt;</span><span style=3D"color:#660">();</span></div></c=
ode></div></div><div><br></div><div>when it's less typing and less noise to=
 just write</div><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">&nbsp; &nbsp; </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">&lt;int&gt;</span><span style=3D"color:#660">();</span></div></code></=
div></div></div></blockquote><div><br>The use case for this:<br><br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><d=
iv class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bor=
der-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word=
-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><span style=3D"color: #606;" class=3D"styled-by-prettify">vector&lt;int&=
gt; v;<br><br>array_view&lt;auto&gt; av =3D v; //deduces to array_view&lt;i=
nt&gt;<br></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify"></span></d=
iv></code></div><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_6383_1902075028.1425489252130--
------=_Part_6382_703121146.1425489252130--

.


Author: Faisal Vali <faisalv@gmail.com>
Date: Wed, 4 Mar 2015 11:28:46 -0600
Raw View
On Wed, Mar 4, 2015 at 6:45 AM, Faisal Vali <faisalv@gmail.com> wrote:
> On Tue, Mar 3, 2015 at 11: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:
>>>
<snip>
>>
>>> 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?
>>
>
> Yes.
>
Hmm - just a minor technicality, but actually, they are not all
redeclarations of the same template, the two that you wrote are
equivalent to each other, but the first one is equivalent to the
following (note the order of the template parameters)
  template<class ... A, class ... B, class... C, class...D>
void f(tuple<B, pair<C,D>...)(*...)(A));

in case anyone cares ...

--

---
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: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 5 Mar 2015 15:19:18 -0800 (PST)
Raw View
------=_Part_29_1498963338.1425597558981
Content-Type: multipart/alternative;
 boundary="----=_Part_30_946158809.1425597558981"

------=_Part_30_946158809.1425597558981
Content-Type: text/plain; charset=UTF-8

I... just... ugh.

I'm fine with type deduction patterns like std::vector<auto> = ...; That's
just a generalization of type deduction in static contexts.

My issue is with, well, any syntax that declares a template without having
to type either the word "template" or the use of "<>" brackets. Templates
are a fundamentally different kind of construct, and we have specific
syntax for doing so. By removing that syntax, it becomes way too easy to
not notice that you've declared a template.

The last thing we should want is for people to accidentally make something
a template.

I accept this with lambdas, because the main point of lambdas is that
they're a short-cut. Furthermore, they have a syntax that's fundamentally
different from regular functions. But for a regular function? No.

Basically, if I see this:

X func_name(...);

I expect that &func_name ought to return a pointer. For it to do something
else, like being a compiler error, would be surprising.

--

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

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

<div dir=3D"ltr">I... just... ugh.<br><br>I'm fine with type deduction patt=
erns like std::vector&lt;auto&gt; =3D ...; That's just a generalization of =
type deduction in static contexts.<br><br>My issue is with, well, any synta=
x that declares a template without having to type either the word "template=
" or the use of "&lt;&gt;" brackets. Templates are a fundamentally differen=
t kind of construct, and we have specific syntax for doing so. By removing =
that syntax, it becomes way too easy to not notice that you've declared a t=
emplate.<br><br>The last thing we should want is for people to accidentally=
 make something a template.<br><br>I accept this with lambdas, because the =
main point of lambdas is that they're a short-cut. Furthermore, they have a=
 syntax that's fundamentally different from regular functions. But for a re=
gular function? No.<br><br>Basically, if I see this:<br><br>X func_name(...=
);<br><br>I expect that &amp;func_name ought to return a pointer. For it to=
 do something else, like being a compiler error, would be surprising.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_30_946158809.1425597558981--
------=_Part_29_1498963338.1425597558981--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 5 Mar 2015 15:46:21 -0800 (PST)
Raw View
------=_Part_77_1554386209.1425599181801
Content-Type: multipart/alternative;
 boundary="----=_Part_78_430448908.1425599181801"

------=_Part_78_430448908.1425599181801
Content-Type: text/plain; charset=UTF-8



On Thursday, March 5, 2015 at 6:19:20 PM UTC-5, Nicol Bolas wrote:
>
> I... just... ugh.
>
> I'm fine with type deduction patterns like std::vector<auto> = ...; That's
> just a generalization of type deduction in static contexts.
>
> My issue is with, well, any syntax that declares a template without having
> to type either the word "template" or the use of "<>" brackets. Templates
> are a fundamentally different kind of construct, and we have specific
> syntax for doing so. By removing that syntax, it becomes way too easy to
> not notice that you've declared a template.
>

You could add a requirement for an empty template <> when using auto.

template <>
auto add(auto x, auto y) { return x + y; }

--

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

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

<div dir=3D"ltr"><br><br>On Thursday, March 5, 2015 at 6:19:20 PM UTC-5, Ni=
col Bolas 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"lt=
r">I... just... ugh.<br><br>I'm fine with type deduction patterns like std:=
:vector&lt;auto&gt; =3D ...; That's just a generalization of type deduction=
 in static contexts.<br><br>My issue is with, well, any syntax that declare=
s a template without having to type either the word "template" or the use o=
f "&lt;&gt;" brackets. Templates are a fundamentally different kind of cons=
truct, and we have specific syntax for doing so. By removing that syntax, i=
t becomes way too easy to not notice that you've declared a template.<br></=
div></blockquote><div><br></div><div>You could add a requirement for an emp=
ty template &lt;&gt; when using auto.</div><div><br></div><div>template &lt=
;&gt;</div><div>auto add(auto x, auto y) { return x + y; }</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_78_430448908.1425599181801--
------=_Part_77_1554386209.1425599181801--

.