Topic: template template aliases?


Author: Eric Niebler <eric.niebler@gmail.com>
Date: Mon, 30 Jan 2017 09:24:00 -0800
Raw View
--f403045e34b4d74bb40547531456
Content-Type: text/plain; charset=UTF-8

Crazy thought.

Why not permit template template aliases?

  template <class A>
  template <class B>
  using Foo = pair<A, B>;

Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.

Why?

Higher order template metaprogramming sometimes requires passing a template
to a template. For example:

  // with C++17 fold expressions
  template <template <class Ts> class Pred, class...Ts>
  constexpr bool all_of = (... && Pred<Ts>::value);

  static_assert(all_of<std::is_scalar, int, short, float>);

Q: How would you use all_of to check that all types in a pack are
convertible to bool?
A: With a "bind"-like template template alias:

  template <template<class...> class Fn, class...As>
  template <class...Bs>
  using bind_back = Fn<Bs..., As...>;

  template <template<class...> class Fn>
  template <class T>
  using unary = Fn<T>;

  static_assert(all_of<unary<bind_back<std::is_convertible, bool>>, int,
short, float>);

What would this language feature break?

Thanks,
Eric

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f8JOZqCzNwB3iKqD_wBACVL_j4EA95MbWR_yr1M%3DR7HbA%40mail.gmail.com.

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

<div dir=3D"ltr">Crazy thought.<div><br></div><div>Why not permit template =
template aliases?</div><div><br></div><div>=C2=A0 template &lt;class A&gt;<=
/div><div>=C2=A0 template &lt;class B&gt;</div><div>=C2=A0 using Foo =3D pa=
ir&lt;A, B&gt;;</div><div><br></div><div>Foo&lt;A&gt; is a unary template s=
uch that Foo&lt;A&gt;&lt;B&gt; is pair&lt;A,B&gt;.</div><div><br></div><div=
>Why?</div><div><br></div><div>Higher order template metaprogramming someti=
mes requires passing a template to a template. For example:<div><br></div><=
div>=C2=A0 // with C++17 fold expressions</div><div>=C2=A0 template &lt;tem=
plate &lt;class Ts&gt; class Pred, class...Ts&gt;</div><div>=C2=A0 constexp=
r bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::value);</div><div><br></d=
iv><div>=C2=A0 static_assert(all_of&lt;std::is_scalar, int, short, float&gt=
;);</div><div><br></div><div>Q: How would you use all_of to check that all =
types in a pack are convertible to bool?</div><div>A: With a &quot;bind&quo=
t;-like template template alias:</div><div><br></div><div>=C2=A0 template &=
lt;template&lt;class...&gt; class Fn, class...As&gt;</div><div>=C2=A0 templ=
ate &lt;class...Bs&gt;</div><div>=C2=A0 using bind_back =3D Fn&lt;Bs..., As=
....&gt;;</div><div><br></div><div>=C2=A0 template &lt;template&lt;class...&=
gt; class Fn&gt;</div><div>=C2=A0 template &lt;class T&gt;</div><div>=C2=A0=
 using unary =3D Fn&lt;T&gt;;</div><div><br></div><div>=C2=A0 static_assert=
(all_of&lt;unary&lt;bind_back&lt;std::is_convertible, bool&gt;&gt;, int, sh=
ort, float&gt;);</div><div><br></div><div>What would this language feature =
break?</div></div><div><br></div><div>Thanks,</div><div>Eric</div><div><br>=
</div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAvM5f8JOZqCzNwB3iKqD_wBACVL_j4EA95M=
bWR_yr1M%3DR7HbA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f8JOZqCzN=
wB3iKqD_wBACVL_j4EA95MbWR_yr1M%3DR7HbA%40mail.gmail.com</a>.<br />

--f403045e34b4d74bb40547531456--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 30 Jan 2017 19:29:02 +0200
Raw View
On 30 January 2017 at 19:24, Eric Niebler <eric.niebler@gmail.com> wrote:
> Crazy thought.
>
> Why not permit template template aliases?
>
>   template <class A>
>   template <class B>
>   using Foo = pair<A, B>;
>
> Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>
> Why?
>
> Higher order template metaprogramming sometimes requires passing a template
> to a template. For example:
>
>   // with C++17 fold expressions
>   template <template <class Ts> class Pred, class...Ts>
>   constexpr bool all_of = (... && Pred<Ts>::value);
>
>   static_assert(all_of<std::is_scalar, int, short, float>);
>
> Q: How would you use all_of to check that all types in a pack are
> convertible to bool?
> A: With a "bind"-like template template alias:
>
>   template <template<class...> class Fn, class...As>
>   template <class...Bs>
>   using bind_back = Fn<Bs..., As...>;
>
>   template <template<class...> class Fn>
>   template <class T>
>   using unary = Fn<T>;
>
>   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>, int,
> short, float>);
>
> What would this language feature break?


It mixes the water about whether an alias is a template (currently it
isn't, it's replaced immediately and
cannot be specialized) or not. That doesn't mean the whole idea is
nuts, but it's probably
something to think about.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUYsJCALYoEWnirrgrmrOGfNZR82%3DaW8JhKSXNos8Q8tiw%40mail.gmail.com.

.


Author: Eric Niebler <eric.niebler@gmail.com>
Date: Mon, 30 Jan 2017 09:31:57 -0800
Raw View
--001a114d9d484df8310547533169
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 9:29 AM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:

> On 30 January 2017 at 19:24, Eric Niebler <eric.niebler@gmail.com> wrote:
> > Crazy thought.
> >
> > Why not permit template template aliases?
> >
> >   template <class A>
> >   template <class B>
> >   using Foo = pair<A, B>;
> >
> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
> >
> > Why?
> >
> > Higher order template metaprogramming sometimes requires passing a
> template
> > to a template. For example:
> >
> >   // with C++17 fold expressions
> >   template <template <class Ts> class Pred, class...Ts>
> >   constexpr bool all_of = (... && Pred<Ts>::value);
> >
> >   static_assert(all_of<std::is_scalar, int, short, float>);
> >
> > Q: How would you use all_of to check that all types in a pack are
> > convertible to bool?
> > A: With a "bind"-like template template alias:
> >
> >   template <template<class...> class Fn, class...As>
> >   template <class...Bs>
> >   using bind_back = Fn<Bs..., As...>;
> >
> >   template <template<class...> class Fn>
> >   template <class T>
> >   using unary = Fn<T>;
> >
> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>, int,
> > short, float>);
> >
> > What would this language feature break?
>
>
> It mixes the water about whether an alias is a template (currently it
> isn't, it's replaced immediately and
> cannot be specialized) or not. That doesn't mean the whole idea is
> nuts, but it's probably
> something to think about.
>


Thanks for the speedy reply, Ville. You can already pass a template alias
as a template template parameter. Is this somehow different?

Eric

P.S. I owe you 2 beers in Kona.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9sOTjz%3DXvtDuF3iF%3DHahdB-xa2q9g8EiyBsxsSiA3ocw%40mail.gmail.com.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Jan 30, 2017 at 9:29 AM, Ville Voutilainen <span dir=3D"ltr">&l=
t;<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.vo=
utilainen@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div class=3D"HOEnZb"><div class=3D"h5">On 30 January 2017 at 19:24, Eric =
Niebler &lt;<a href=3D"mailto:eric.niebler@gmail.com">eric.niebler@gmail.co=
m</a>&gt; wrote:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;<wbr>bind_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
<br>
<br>
</div></div>It mixes the water about whether an alias is a template (curren=
tly it<br>
isn&#39;t, it&#39;s replaced immediately and<br>
cannot be specialized) or not. That doesn&#39;t mean the whole idea is<br>
nuts, but it&#39;s probably<br>
something to think about.<br></blockquote><div><br></div><div><br></div><di=
v>Thanks for the speedy reply, Ville. You can already pass a template alias=
 as a template template parameter. Is this somehow different?</div><div><br=
></div><div>Eric</div><div><br></div><div>P.S. I owe you 2 beers in Kona.</=
div><div><br></div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9sOTjz%3DXvtDuF3iF%3DHahdB-xa2=
q9g8EiyBsxsSiA3ocw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9sOTjz=
%3DXvtDuF3iF%3DHahdB-xa2q9g8EiyBsxsSiA3ocw%40mail.gmail.com</a>.<br />

--001a114d9d484df8310547533169--

.


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 30 Jan 2017 18:38:53 +0100
Raw View
2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
> Crazy thought.
>
> Why not permit template template aliases?
>
>   template <class A>
>   template <class B>
>   using Foo = pair<A, B>;
>
> Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>
> Why?
>
> Higher order template metaprogramming sometimes requires passing a template
> to a template. For example:
>
>   // with C++17 fold expressions
>   template <template <class Ts> class Pred, class...Ts>
>   constexpr bool all_of = (... && Pred<Ts>::value);
>
>   static_assert(all_of<std::is_scalar, int, short, float>);
>
> Q: How would you use all_of to check that all types in a pack are
> convertible to bool?
> A: With a "bind"-like template template alias:
>
>   template <template<class...> class Fn, class...As>
>   template <class...Bs>
>   using bind_back = Fn<Bs..., As...>;
>
>   template <template<class...> class Fn>
>   template <class T>
>   using unary = Fn<T>;
>
>   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>, int,
> short, float>);
>
> What would this language feature break?
>

Some note about the syntax. I think you need to extend it so that
"template" can be put after the angle brackets aswell?

    template<typename T>
    struct A { template<typename A> template<typename B> using X =
void (A::*)(B); };

    template<typename T>
    void f() {
       typename T::template X<string> template<size_t> p = &string::resize;
    }

    int main() { f<A>(); }

Note the second "template" disambiguator.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANu6V4U0GDA5Zoi7Ri-fvBp%2BeM05gXYawQghu69MGTkdS3%3D91Q%40mail.gmail.com.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 30 Jan 2017 19:39:31 +0200
Raw View
On 30 January 2017 at 19:31, Eric Niebler <eric.niebler@gmail.com> wrote:
>> It mixes the water about whether an alias is a template (currently it
>> isn't, it's replaced immediately and
>> cannot be specialized) or not. That doesn't mean the whole idea is
>> nuts, but it's probably
>> something to think about.
> Thanks for the speedy reply, Ville. You can already pass a template alias as
> a template template parameter. Is this somehow different?

Maybe not, as that is also mixing the design waters. :) On the other
hand, I'd think
that in those cases the alias must alias an actual template, instead
of mapping to a non-template.
The alias template template looks like it defines an actual template,
not an alias that it's replaced
right then-and-there where it's used.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZS5p8Ko3-1TVONv5J2kneCSKDAJiwL3cTx60ktDLAg0A%40mail.gmail.com.

.


Author: Eric Niebler <eric.niebler@gmail.com>
Date: Mon, 30 Jan 2017 10:10:14 -0800
Raw View
--001a11439676349fe5054753ba9d
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 9:38 AM, 'Johannes Schaub' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

> 2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
> > Crazy thought.
> >
> > Why not permit template template aliases?
> >
> >   template <class A>
> >   template <class B>
> >   using Foo = pair<A, B>;
> >
> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
> >
> > Why?
> >
> > Higher order template metaprogramming sometimes requires passing a
> template
> > to a template. For example:
> >
> >   // with C++17 fold expressions
> >   template <template <class Ts> class Pred, class...Ts>
> >   constexpr bool all_of = (... && Pred<Ts>::value);
> >
> >   static_assert(all_of<std::is_scalar, int, short, float>);
> >
> > Q: How would you use all_of to check that all types in a pack are
> > convertible to bool?
> > A: With a "bind"-like template template alias:
> >
> >   template <template<class...> class Fn, class...As>
> >   template <class...Bs>
> >   using bind_back = Fn<Bs..., As...>;
> >
> >   template <template<class...> class Fn>
> >   template <class T>
> >   using unary = Fn<T>;
> >
> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>, int,
> > short, float>);
> >
> > What would this language feature break?
> >
>
> Some note about the syntax. I think you need to extend it so that
> "template" can be put after the angle brackets aswell?
>
>     template<typename T>
>     struct A { template<typename A> template<typename B> using X =
> void (A::*)(B); };
>
>     template<typename T>
>     void f() {
>        typename T::template X<string> template<size_t> p = &string::resize;
>     }
>
>     int main() { f<A>(); }
>
> Note the second "template" disambiguator.
>


Yuk. Or maybe:

    template<typename T>
    void f() {
       typename T::template template X<string><size_t> p = &string::resize;
    }

Also, yuk. On the plus side, the existence of template template aliases
would obviate most of the need to nest a template (template) alias in a
struct.

Eric

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ZZ6U-kPcrUBaZfjCH25urYwdM4OesLR61op9uEi4dJw%40mail.gmail.com.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Jan 30, 2017 at 9:38 AM, &#39;Johannes Schaub&#39; via ISO C++ =
Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-pro=
posals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=3D=
"gmail-HOEnZb"><div class=3D"gmail-h5">2017-01-30 18:24 GMT+01:00 Eric Nieb=
ler &lt;<a href=3D"mailto:eric.niebler@gmail.com">eric.niebler@gmail.com</a=
>&gt;:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;<wbr>bind_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
&gt;<br>
<br>
</div></div>Some note about the syntax. I think you need to extend it so th=
at<br>
&quot;template&quot; can be put after the angle brackets aswell?<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 struct A { template&lt;typename A&gt; template&lt;typename B&=
gt; using X =3D<br>
void (A::*)(B); };<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 void f() {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template X&lt;string&gt; template&lt=
;size_t&gt; p =3D &amp;string::resize;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 int main() { f&lt;A&gt;(); }<br>
<br>
Note the second &quot;template&quot; disambiguator.<br></blockquote><div><b=
r></div><div><br></div><div>Yuk. Or maybe:</div><div><br></div><div>=C2=A0 =
=C2=A0 template&lt;typename T&gt;<br>=C2=A0 =C2=A0 void f() {<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0typename T::template template X&lt;string&gt;&lt;size_t&gt=
; p =3D &amp;string::resize;<br>=C2=A0 =C2=A0 }<br></div><div><br></div><di=
v>Also, yuk. On the plus side, the existence of template template aliases w=
ould obviate most of the need to nest a template (template) alias in a stru=
ct.<br></div><div><br></div><div>Eric</div><div><br></div><div><br></div></=
div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ZZ6U-kPcrUBaZfjCH25urYwdM4Oes=
LR61op9uEi4dJw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ZZ6U-kPcr=
UBaZfjCH25urYwdM4OesLR61op9uEi4dJw%40mail.gmail.com</a>.<br />

--001a11439676349fe5054753ba9d--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 30 Jan 2017 13:14:24 -0500
Raw View
--94eb2c032f1011fb3c054753c93d
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 1:10 PM, Eric Niebler <eric.niebler@gmail.com>
wrote:

> Also, yuk. On the plus side, the existence of template template aliases
> would obviate most of the need to nest a template (template) alias in a
> struct.
>

I agree that it would be nice to make such an alias, though the need for
disambiguation is really unfortunate. I'd be for something in this area
regardless, but I suspect it may be difficult to get by some people.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEn7d6OwTg16rseM0_siXX83Crkkf9GRqFUM66CpJy-S7w%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jan 30, 2017 at 1:10 PM, Eric Niebler <span dir=3D"ltr">&lt;<a href=3D"=
mailto:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@gmail.com</a>=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div =
class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Also, yuk. On the plu=
s side, the existence of template template aliases would obviate most of th=
e need to nest a template (template) alias in a struct.</div></div></div></=
div></blockquote><div><br></div><div>I agree that it would be nice to make =
such an alias, though the need for disambiguation is really unfortunate. I&=
#39;d be for something in this area regardless, but I suspect it may be dif=
ficult to get by some people.</div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEn7d6OwTg16rseM0_siXX83Crkkf9GR=
qFUM66CpJy-S7w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEn7d6OwTg16=
rseM0_siXX83Crkkf9GRqFUM66CpJy-S7w%40mail.gmail.com</a>.<br />

--94eb2c032f1011fb3c054753c93d--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 30 Jan 2017 11:47:26 -0800
Raw View
--001a1147c6c80135590547551751
Content-Type: text/plain; charset=UTF-8

On 30 January 2017 at 10:10, Eric Niebler <eric.niebler@gmail.com> wrote:

> On Mon, Jan 30, 2017 at 9:38 AM, 'Johannes Schaub' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
>> 2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
>> > Crazy thought.
>> >
>> > Why not permit template template aliases?
>> >
>> >   template <class A>
>> >   template <class B>
>> >   using Foo = pair<A, B>;
>> >
>> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>> >
>> > Why?
>> >
>> > Higher order template metaprogramming sometimes requires passing a
>> template
>> > to a template. For example:
>> >
>> >   // with C++17 fold expressions
>> >   template <template <class Ts> class Pred, class...Ts>
>> >   constexpr bool all_of = (... && Pred<Ts>::value);
>> >
>> >   static_assert(all_of<std::is_scalar, int, short, float>);
>> >
>> > Q: How would you use all_of to check that all types in a pack are
>> > convertible to bool?
>> > A: With a "bind"-like template template alias:
>> >
>> >   template <template<class...> class Fn, class...As>
>> >   template <class...Bs>
>> >   using bind_back = Fn<Bs..., As...>;
>> >
>> >   template <template<class...> class Fn>
>> >   template <class T>
>> >   using unary = Fn<T>;
>> >
>> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>,
>> int,
>> > short, float>);
>> >
>> > What would this language feature break?
>> >
>>
>> Some note about the syntax. I think you need to extend it so that
>> "template" can be put after the angle brackets aswell?
>>
>>     template<typename T>
>>     struct A { template<typename A> template<typename B> using X =
>> void (A::*)(B); };
>>
>>     template<typename T>
>>     void f() {
>>        typename T::template X<string> template<size_t> p =
>> &string::resize;
>>     }
>>
>>     int main() { f<A>(); }
>>
>> Note the second "template" disambiguator.
>>
>
>
> Yuk. Or maybe:
>
>     template<typename T>
>     void f() {
>        typename T::template template X<string><size_t> p = &string::resize;
>     }
>
> Also, yuk. On the plus side, the existence of template template aliases
> would obviate most of the need to nest a template (template) alias in a
> struct.
>

It's probably useful to look at the proposal side-by-side with how we might
write it today:

  template <template<class...> class Fn, class...As>
  template <class...Bs>
  using bind_back = Fn<Bs..., As...>;

  // 'unary' is not required any more, per P0522
  static_assert(all_of<bind_back<std::is_convertible, bool>, int, short,
float>);

vs

  template <template<class...> class Fn, class...As>
  struct bind_back {
    template <class...Bs>
    using apply = Fn<Bs..., As...>;
  };

  static_assert(all_of<bind_back<std::is_convertible, bool>::template
apply, int, short, float>);

(with one difference being that template argument deduction can presumably
look through a curried alias template, but can't look through the class
template formulation).


Another way to get a similar effect would be to allow partial application
of templates at the point of use instead of allowing currying in the
definition. So (strawman syntax):

  static_assert(all_of<std::is_convertible<bool, _1>, int, short, float>);

where std::is_convertible<bool, _1> is a type lambda, with the above being
shorthand for

  template<typename T> using X = std::is_convertible<bool, T>;
  static_assert(all_of<X, int, short, float>);

(In fact, I think you can implement an _1 and an all_of sufficient to
support the above as a library, but it would have a lot of limitations.)

Or we could support type lambdas directly (again, strawman syntax):

  static_assert(all_of<[]<typename T> -> std::is_convertible<bool, T>, int,
short, float>);

These don't quite provide the full power of your curried alias templates,
though; I don't see a way to get the effect of

  template<typename ...A> template<typename ...B> using X =
pair<tuple<A...>, tuple<B...>>;

.... since the above alternatives don't provide a way to specify where the
end of the first pack is. We could perhaps get that effect with another
extension:

  template<typename ...A, typename ...B> using X = pair<tuple<A...>,
tuple<B...>>;
  X<int, char; float> pt; // pair<tuple<int, char>, tuple<float>>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmkNy3vXhTmx6YmQ5StNOjo02TTDBh%3DSCQ_tNfoqkrhvQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 3=
0 January 2017 at 10:10, Eric Niebler <span dir=3D"ltr">&lt;<a href=3D"mail=
to:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@gmail.com</a>&gt;=
</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div di=
r=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><div c=
lass=3D"gmail-h5">On Mon, Jan 30, 2017 at 9:38 AM, &#39;Johannes Schaub&#39=
; via ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"=
mailto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div class=3D"gmail-m_232073812449960824gmail-HOEnZb"><div class=3D"gmail-=
m_232073812449960824gmail-h5">2017-01-30 18:24 GMT+01:00 Eric Niebler &lt;<=
a href=3D"mailto:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@gma=
il.com</a>&gt;:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;bi<wbr>nd_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
&gt;<br>
<br>
</div></div>Some note about the syntax. I think you need to extend it so th=
at<br>
&quot;template&quot; can be put after the angle brackets aswell?<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 struct A { template&lt;typename A&gt; template&lt;typename B&=
gt; using X =3D<br>
void (A::*)(B); };<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 void f() {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template X&lt;string&gt; template&lt=
;size_t&gt; p =3D &amp;string::resize;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 int main() { f&lt;A&gt;(); }<br>
<br>
Note the second &quot;template&quot; disambiguator.<br></blockquote><div><b=
r></div><div><br></div></div></div><div>Yuk. Or maybe:</div><div><br></div>=
<div><span class=3D"gmail-">=C2=A0 =C2=A0 template&lt;typename T&gt;<br>=C2=
=A0 =C2=A0 void f() {<br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::temp=
late template X&lt;string&gt;&lt;size_t&gt; p =3D &amp;string::resize;<br>=
=C2=A0 =C2=A0 }<br></div><div><br></div><div>Also, yuk. On the plus side, t=
he existence of template template aliases would obviate most of the need to=
 nest a template (template) alias in a struct.</div></div></div></div></blo=
ckquote><div><br></div><div>It&#39;s probably useful to look at the proposa=
l side-by-side with how we might write it today:</div><div><br></div><div><=
div>=C2=A0 template &lt;template&lt;class...&gt; class Fn, class...As&gt;</=
div><div>=C2=A0 template &lt;class...Bs&gt;</div><div>=C2=A0 using bind_bac=
k =3D Fn&lt;Bs..., As...&gt;;</div><div><br></div><div>=C2=A0 // &#39;unary=
&#39; is not required any more, per P0522</div><div>=C2=A0 static_assert(al=
l_of&lt;bind_back&lt;std::is_convertible, bool&gt;, int, short, float&gt;);=
</div></div><div><br></div><div>vs</div><div><br></div><div>=C2=A0 template=
 &lt;template&lt;class...&gt; class Fn, class...As&gt;</div><div>=C2=A0 str=
uct bind_back {</div><div>=C2=A0 =C2=A0 template &lt;class...Bs&gt;</div><d=
iv>=C2=A0 =C2=A0 using apply =3D Fn&lt;Bs..., As...&gt;;</div><div>=C2=A0 }=
;</div><div><br></div><div><div>=C2=A0 static_assert(all_of&lt;bind_back&lt=
;std::is_convertible, bool&gt;::template apply, int, short, float&gt;);</di=
v></div><div><br></div><div>(with one difference being that template argume=
nt deduction can presumably look through a curried alias template, but can&=
#39;t look through the class template formulation).</div><div><br></div><di=
v><br></div><div>Another way to get a similar effect would be to allow part=
ial application of templates at the point of use instead of allowing curryi=
ng in the definition. So (strawman syntax):</div><div><br></div><div>=C2=A0=
 static_assert(all_of&lt;std::is_convertible&lt;bool, _1&gt;, int, short, f=
loat&gt;);<br></div><div><br></div><div>where std::is_convertible&lt;bool, =
_1&gt; is a type lambda, with the above being shorthand for</div><div><br><=
/div><div>=C2=A0 template&lt;typename T&gt; using X =3D std::is_convertible=
&lt;bool, T&gt;;</div><div>=C2=A0 static_assert(all_of&lt;X, int, short, fl=
oat&gt;);<br></div><div><br></div><div>(In fact, I think you can implement =
an _1 and an all_of sufficient to support the above as a library, but it wo=
uld have a lot of limitations.)</div><div><br></div><div>Or we could suppor=
t type lambdas directly (again, strawman syntax):</div><div><br></div><div>=
<div>=C2=A0 static_assert(all_of&lt;[]&lt;typename T&gt; -&gt; std::is_conv=
ertible&lt;bool, T&gt;, int, short, float&gt;);</div></div><div><br></div><=
div><div>These don&#39;t quite provide the full power of your curried alias=
 templates, though; I don&#39;t see a way to get the effect of</div><div><b=
r></div><div>=C2=A0 template&lt;typename ...A&gt; template&lt;typename ...B=
&gt; using X =3D pair&lt;tuple&lt;A...&gt;, tuple&lt;B...&gt;&gt;;</div><di=
v><br></div><div>... since the above alternatives don&#39;t provide a way t=
o specify where the end of the first pack is. We could perhaps get that eff=
ect with another extension:</div></div><div><br></div><div>=C2=A0 template&=
lt;typename ...A, typename ...B&gt; using X =3D pair&lt;tuple&lt;A...&gt;, =
tuple&lt;B...&gt;&gt;;</div><div>=C2=A0 X&lt;int, char; float&gt; pt; // pa=
ir&lt;tuple&lt;int, char&gt;, tuple&lt;float&gt;&gt;</div></div></div></div=
>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmkNy3vXhTmx6YmQ5StNOjo02TTDBh%=
3DSCQ_tNfoqkrhvQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmkNy3vXh=
Tmx6YmQ5StNOjo02TTDBh%3DSCQ_tNfoqkrhvQ%40mail.gmail.com</a>.<br />

--001a1147c6c80135590547551751--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 30 Jan 2017 15:22:53 -0500
Raw View
--94eb2c096f3e8a45c90547559442
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 2:47 PM, Richard Smith <richard@metafoo.co.uk>
wrote:

> Another way to get a similar effect would be to allow partial application
> of templates at the point of use instead of allowing currying in the
> definition. So (strawman syntax):
>

>   static_assert(all_of<std::is_convertible<bool, _1>, int, short, float>);
>
> where std::is_convertible<bool, _1> is a type lambda, with the above being
> shorthand for
>
>   template<typename T> using X = std::is_convertible<bool, T>;
>   static_assert(all_of<X, int, short, float>);
>
> (In fact, I think you can implement an _1 and an all_of sufficient to
> support the above as a library, but it would have a lot of limitations.)
>

That's not exactly a strawman -- Boost.MPL has had such lambdas since it
was introduced in the early 2000s. The equivalent lambda in MPL-land would
be std::is_convertible<bool, boost::mpl::_1>. In current MPL, you can apply
an MPL lambda or a "normal" metafunction class with boost::mpl::apply (in
some ways akin to a std::invoke of the metafunction world). I don't believe
MPL has an all_of algorithm, but it does have other algorithms. FWIW,
despite the magic involved, I've always found MPL's lambda facilities
better than the runtime Boost.Lambda facilties (partly because the problem
is in some ways simpler -- no value/reference binding specification, etc.).

Anyway, as someone who's done a decent amount of C++98/03 metaprogramming,
it's unfortunately no replacement for a language feature. If the complexity
of the tricks involved wasn't already enough, it's impossible to make it
work consistently with arbitrary template parameter kinds (MPL lambdas live
in a world of templates whose only template parameter kinds are types).
During composition, you can also run into the subtleties that require an
equivalent of boost::protect (mpl has a corresponding boost::mpl::protect).

I'd rather we not continue down the library route for this stuff.

On Mon, Jan 30, 2017 at 2:47 PM, Richard Smith <richard@metafoo.co.uk>
 wrote:

> Or we could support type lambdas directly (again, strawman syntax):
>
>   static_assert(all_of<[]<typename T> -> std::is_convertible<bool, T>,
> int, short, float>);
>

This seems much more reasonable to me, though I suspect that, due to its
dealing with metaprogramming, it would see push-back from some people.

On Mon, Jan 30, 2017 at 2:47 PM, Richard Smith <richard@metafoo.co.uk>
 wrote:

> ... since the above alternatives don't provide a way to specify where the
> end of the first pack is. We could perhaps get that effect with another
> extension:
>
>   template<typename ...A, typename ...B> using X = pair<tuple<A...>,
> tuple<B...>>;
>   X<int, char; float> pt; // pair<tuple<int, char>, tuple<float>>
>

Interesting idea.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnSUxxC2BojM%2BB8qpiOvrOo0qsA8stn_Yz3CMOUKD6b%2BQ%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jan 30, 2017 at 2:47 PM, Richard Smith <span dir=3D"ltr">&lt;<a href=3D=
"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div=
 dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><di=
v class=3D"gmail-h5"><div><span style=3D"color:rgb(34,34,34)">Another way t=
o get a similar effect would be to allow partial application of templates a=
t the point of use instead of allowing currying in the definition. So (stra=
wman syntax):</span><br></div></div></div></div></div></div></blockquote><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div><br></div><div>=C2=A0 stat=
ic_assert(all_of&lt;std::is_<wbr>convertible&lt;bool, _1&gt;, int, short, f=
loat&gt;);<br></div><div><br></div><div>where std::is_convertible&lt;bool, =
_1&gt; is a type lambda, with the above being shorthand for</div><div><br><=
/div><div>=C2=A0 template&lt;typename T&gt; using X =3D std::is_convertible=
&lt;bool, T&gt;;</div><div>=C2=A0 static_assert(all_of&lt;X, int, short, fl=
oat&gt;);<br></div><div><br></div><div>(In fact, I think you can implement =
an _1 and an all_of sufficient to support the above as a library, but it wo=
uld have a lot of limitations.)</div></div></div></div></blockquote><div><b=
r></div><div>That&#39;s not exactly a strawman -- Boost.MPL has had such la=
mbdas since it was introduced in the early 2000s. The equivalent lambda in =
MPL-land would be std::is_convertible&lt;bool, boost::mpl::_1&gt;. In curre=
nt MPL, you can apply an MPL lambda or a &quot;normal&quot; metafunction cl=
ass with boost::mpl::apply (in some ways akin to a std::invoke of the metaf=
unction world). I don&#39;t believe MPL has an all_of algorithm, but it doe=
s have other algorithms. FWIW, despite the magic involved, I&#39;ve always =
found MPL&#39;s lambda facilities better than the runtime Boost.Lambda faci=
lties (partly because the problem is in some ways simpler -- no value/refer=
ence binding specification, etc.).</div><div><br></div><div>Anyway, as some=
one who&#39;s done a decent amount of C++98/03 metaprogramming, it&#39;s un=
fortunately no replacement for a language feature. If the complexity of the=
 tricks involved wasn&#39;t already enough, it&#39;s impossible to make it =
work consistently with arbitrary template parameter kinds (MPL lambdas live=
 in a world of templates whose only template parameter kinds are types). Du=
ring composition, you can also run into the subtleties that require an equi=
valent of boost::protect (mpl has a corresponding boost::mpl::protect).<br>=
<br></div><div>I&#39;d rather we not continue down the library route for th=
is stuff.</div><div><br></div><div>On Mon, Jan 30, 2017 at 2:47 PM, Richard=
 Smith=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:richard@metafoo.co.uk" =
target=3D"_blank">richard@metafoo.co.uk</a>&gt;</span>=C2=A0wrote:</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>Or we could support type l=
ambdas directly (again, strawman syntax):</div><div><br></div><div><div>=C2=
=A0 static_assert(all_of&lt;[]&lt;<wbr>typename T&gt; -&gt; std::is_convert=
ible&lt;bool, T&gt;, int, short, float&gt;);</div></div></div></div></div><=
/blockquote><div><br></div><div>This seems much more reasonable to me, thou=
gh I suspect that, due to its dealing with metaprogramming, it would see pu=
sh-back from some people.</div><div><br></div><div>On Mon, Jan 30, 2017 at =
2:47 PM, Richard Smith=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:richard=
@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt;</span>=C2=
=A0wrote:=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div=
 dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><di=
v></div><div>... since the above alternatives don&#39;t provide a way to sp=
ecify where the end of the first pack is. We could perhaps get that effect =
with another extension:</div></div><div><br></div><div>=C2=A0 template&lt;t=
ypename ...A, typename ...B&gt; using X =3D pair&lt;tuple&lt;A...&gt;, tupl=
e&lt;B...&gt;&gt;;</div><div>=C2=A0 X&lt;int, char; float&gt; pt; // pair&l=
t;tuple&lt;int, char&gt;, tuple&lt;float&gt;&gt;</div></div></div></div></b=
lockquote><div><br></div><div>Interesting idea.</div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DEnSUxxC2BojM%2BB8qpiOvrOo0qsA8s=
tn_Yz3CMOUKD6b%2BQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DEnSUxxC=
2BojM%2BB8qpiOvrOo0qsA8stn_Yz3CMOUKD6b%2BQ%40mail.gmail.com</a>.<br />

--94eb2c096f3e8a45c90547559442--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 30 Jan 2017 15:47:09 -0500
Raw View
--001a1134fa545c9e64054755ebbd
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 3:22 PM, Matt Calabrese <calabrese@google.com>
wrote:

> Anyway, as someone who's done a decent amount of C++98/03 metaprogramming,
> it's unfortunately no replacement for a language feature. If the complexity
> of the tricks involved wasn't already enough, it's impossible to make it
> work consistently with arbitrary template parameter kinds (MPL lambdas live
> in a world of templates whose only template parameter kinds are types).
>

On that note, though, I recall that James Touton has voiced a desire for an
"any-template-parameter-kind" kind (sort of like the new "auto" template
parameters, but would match *any* template parameter kind). He may even be
actively working on such a proposal. That would at least make a
library-level MPL-style lambda facility more capable, but still no
replacement for something in the language.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DBw%2BAfQ-5ZVY1cE6NmqVjeLMZh4CN_Ne%3Dn6BSsU1wVTg%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jan 30, 2017 at 3:22 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>An=
yway, as someone who&#39;s done a decent amount of C++98/03 metaprogramming=
, it&#39;s unfortunately no replacement for a language feature. If the comp=
lexity of the tricks involved wasn&#39;t already enough, it&#39;s impossibl=
e to make it work consistently with arbitrary template parameter kinds (MPL=
 lambdas live in a world of templates whose only template parameter kinds a=
re types).<br></div></div></div></div></blockquote><div><br></div><div>On t=
hat note, though, I recall that James Touton has voiced a desire for an &qu=
ot;any-template-parameter-kind&quot; kind (sort of like the new &quot;auto&=
quot; template parameters, but would match *any* template parameter kind). =
He may even=C2=A0be actively working on such a proposal. That would at leas=
t make a library-level MPL-style lambda facility more capable, but still no=
 replacement for something in the language.</div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DBw%2BAfQ-5ZVY1cE6NmqVjeLMZh=
4CN_Ne%3Dn6BSsU1wVTg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DB=
w%2BAfQ-5ZVY1cE6NmqVjeLMZh4CN_Ne%3Dn6BSsU1wVTg%40mail.gmail.com</a>.<br />

--001a1134fa545c9e64054755ebbd--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 30 Jan 2017 12:58:02 -0800
Raw View
--001a11423ae880ac2205475613ad
Content-Type: text/plain; charset=UTF-8

On 30 January 2017 at 12:47, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals <std-proposals@isocpp.org> wrote:

> On Mon, Jan 30, 2017 at 3:22 PM, Matt Calabrese <calabrese@google.com>
> wrote:
>
>> Anyway, as someone who's done a decent amount of C++98/03
>> metaprogramming, it's unfortunately no replacement for a language feature.
>> If the complexity of the tricks involved wasn't already enough, it's
>> impossible to make it work consistently with arbitrary template parameter
>> kinds (MPL lambdas live in a world of templates whose only template
>> parameter kinds are types).
>>
>
> On that note, though, I recall that James Touton has voiced a desire for
> an "any-template-parameter-kind" kind (sort of like the new "auto" template
> parameters, but would match *any* template parameter kind). He may even be
> actively working on such a proposal. That would at least make a
> library-level MPL-style lambda facility more capable, but still no
> replacement for something in the language.
>

Even with such a facility (which I think we sorely need), you still
presumably couldn't fully support non-type template arguments nor packs
with a library-only approach: given

  template<int N> struct A {};

there's no way that A<_1> can mean anything other than A<N> for some
specific integer N. Likewise, A<B<_1onwards>...> can't work because there's
no way to inject a pack in that position. So generally I agree that a
language solution is strongly preferable here (either a direct solution or
some more general language changes that make a complete library solution
reasonable).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmpy-5pgvJT2LNadnMnokNQ6sgLtTXbQXoYYD-HnsedAw%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 3=
0 January 2017 at 12:47, &#39;Matt Calabrese&#39; via ISO C++ Standard - Fu=
ture Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D"gmail-">On Mon,=
 Jan 30, 2017 at 3:22 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>&gt;<=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Anyway,=
 as someone who&#39;s done a decent amount of C++98/03 metaprogramming, it&=
#39;s unfortunately no replacement for a language feature. If the complexit=
y of the tricks involved wasn&#39;t already enough, it&#39;s impossible to =
make it work consistently with arbitrary template parameter kinds (MPL lamb=
das live in a world of templates whose only template parameter kinds are ty=
pes).<br></div></div></div></div></blockquote><div><br></div></span><div>On=
 that note, though, I recall that James Touton has voiced a desire for an &=
quot;any-template-parameter-kind&quot; kind (sort of like the new &quot;aut=
o&quot; template parameters, but would match *any* template parameter kind)=
.. He may even=C2=A0be actively working on such a proposal. That would at le=
ast make a library-level MPL-style lambda facility more capable, but still =
no replacement for something in the language.</div></div></div></div></bloc=
kquote><div><br></div><div>Even with such a facility (which I think we sore=
ly need), you still presumably couldn&#39;t fully support non-type template=
 arguments nor packs with a library-only approach: given</div><div><br></di=
v><div>=C2=A0 template&lt;int N&gt; struct A {};=C2=A0</div><div><br></div>=
<div><div>there&#39;s no way that A&lt;_1&gt; can mean anything other than =
A&lt;N&gt; for some specific integer N. Likewise, A&lt;B&lt;_1onwards&gt;..=
..&gt; can&#39;t work because there&#39;s no way to inject a pack in that po=
sition. So generally I agree that a language solution is strongly preferabl=
e here (either a direct solution or some more general language changes that=
 make a complete library solution reasonable).</div></div></div></div></div=
>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmpy-5pgvJT2LNadnMnokNQ6sgLtTXb=
QXoYYD-HnsedAw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqmpy-5pgvJT=
2LNadnMnokNQ6sgLtTXbQXoYYD-HnsedAw%40mail.gmail.com</a>.<br />

--001a11423ae880ac2205475613ad--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 30 Jan 2017 16:48:36 -0500
Raw View
--001a114088501e189f054756c7b0
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 3:58 PM, Richard Smith <richard@metafoo.co.uk>
wrote:

> On 30 January 2017 at 12:47, 'Matt Calabrese' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
>> On Mon, Jan 30, 2017 at 3:22 PM, Matt Calabrese <calabrese@google.com>
>> wrote:
>>
>>> Anyway, as someone who's done a decent amount of C++98/03
>>> metaprogramming, it's unfortunately no replacement for a language feature.
>>> If the complexity of the tricks involved wasn't already enough, it's
>>> impossible to make it work consistently with arbitrary template parameter
>>> kinds (MPL lambdas live in a world of templates whose only template
>>> parameter kinds are types).
>>>
>>
>> On that note, though, I recall that James Touton has voiced a desire for
>> an "any-template-parameter-kind" kind (sort of like the new "auto" template
>> parameters, but would match *any* template parameter kind). He may even be
>> actively working on such a proposal. That would at least make a
>> library-level MPL-style lambda facility more capable, but still no
>> replacement for something in the language.
>>
>
> Even with such a facility (which I think we sorely need), you still
> presumably couldn't fully support non-type template arguments nor packs
> with a library-only approach: given
>
>   template<int N> struct A {};
>
> there's no way that A<_1> can mean anything other than A<N> for some
> specific integer N.
>

Right, *this* syntax wouldn't be usable in that case. In those specific
kinds of cases you would use some explicit binding syntax, like bind<A,
_1>. Perhaps a more concrete example would be bind<std::array, int, _1>. I
*think* that should be easily implementable.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DN%2BWkrGmBET0kbRtZZxAE7fWHOsRcU%3DpDHuSx0zsxCmg%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jan 30, 2017 at 3:58 PM, Richard Smith <span dir=3D"ltr">&lt;<a href=3D=
"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><div><div class=3D"m_-64750=
84271488917280h5">On 30 January 2017 at 12:47, &#39;Matt Calabrese&#39; via=
 ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div=
 dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span cl=
ass=3D"m_-6475084271488917280m_-4681168260625194970gmail-">On Mon, Jan 30, =
2017 at 3:22 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=3D"mailto:cal=
abrese@google.com" target=3D"_blank">calabrese@google.com</a>&gt;</span> wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">=
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Anyway, as someo=
ne who&#39;s done a decent amount of C++98/03 metaprogramming, it&#39;s unf=
ortunately no replacement for a language feature. If the complexity of the =
tricks involved wasn&#39;t already enough, it&#39;s impossible to make it w=
ork consistently with arbitrary template parameter kinds (MPL lambdas live =
in a world of templates whose only template parameter kinds are types).<br>=
</div></div></div></div></blockquote><div><br></div></span><div>On that not=
e, though, I recall that James Touton has voiced a desire for an &quot;any-=
template-parameter-kind&quot; kind (sort of like the new &quot;auto&quot; t=
emplate parameters, but would match *any* template parameter kind). He may =
even=C2=A0be actively working on such a proposal. That would at least make =
a library-level MPL-style lambda facility more capable, but still no replac=
ement for something in the language.</div></div></div></div></blockquote><d=
iv><br></div></div></div><div>Even with such a facility (which I think we s=
orely need), you still presumably couldn&#39;t fully support non-type templ=
ate arguments nor packs with a library-only approach: given</div><div><br><=
/div><div>=C2=A0 template&lt;int N&gt; struct A {};=C2=A0</div><div><br></d=
iv><div><div>there&#39;s no way that A&lt;_1&gt; can mean anything other th=
an A&lt;N&gt; for some specific integer N.</div></div></div></div></div></b=
lockquote><div><br></div><div>Right, *this* syntax wouldn&#39;t be usable i=
n that case. In those specific kinds of cases you would use some explicit b=
inding syntax, like bind&lt;A, _1&gt;. Perhaps a more concrete example woul=
d be bind&lt;std::array, int, _1&gt;. I *think* that should be easily imple=
mentable.</div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DN%2BWkrGmBET0kbRtZZxAE7fWHO=
sRcU%3DpDHuSx0zsxCmg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE%3DN=
%2BWkrGmBET0kbRtZZxAE7fWHOsRcU%3DpDHuSx0zsxCmg%40mail.gmail.com</a>.<br />

--001a114088501e189f054756c7b0--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 30 Jan 2017 14:26:04 -0800
Raw View
--f403045d606c5456aa0547574ed5
Content-Type: text/plain; charset=UTF-8

On 30 January 2017 at 13:48, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals <std-proposals@isocpp.org> wrote:

> On Mon, Jan 30, 2017 at 3:58 PM, Richard Smith <richard@metafoo.co.uk>
> wrote:
>
>> On 30 January 2017 at 12:47, 'Matt Calabrese' via ISO C++ Standard -
>> Future Proposals <std-proposals@isocpp.org> wrote:
>>
>>> On Mon, Jan 30, 2017 at 3:22 PM, Matt Calabrese <calabrese@google.com>
>>> wrote:
>>>
>>>> Anyway, as someone who's done a decent amount of C++98/03
>>>> metaprogramming, it's unfortunately no replacement for a language feature.
>>>> If the complexity of the tricks involved wasn't already enough, it's
>>>> impossible to make it work consistently with arbitrary template parameter
>>>> kinds (MPL lambdas live in a world of templates whose only template
>>>> parameter kinds are types).
>>>>
>>>
>>> On that note, though, I recall that James Touton has voiced a desire for
>>> an "any-template-parameter-kind" kind (sort of like the new "auto" template
>>> parameters, but would match *any* template parameter kind). He may even be
>>> actively working on such a proposal. That would at least make a
>>> library-level MPL-style lambda facility more capable, but still no
>>> replacement for something in the language.
>>>
>>
>> Even with such a facility (which I think we sorely need), you still
>> presumably couldn't fully support non-type template arguments nor packs
>> with a library-only approach: given
>>
>>   template<int N> struct A {};
>>
>> there's no way that A<_1> can mean anything other than A<N> for some
>> specific integer N.
>>
>
> Right, *this* syntax wouldn't be usable in that case. In those specific
> kinds of cases you would use some explicit binding syntax, like bind<A,
> _1>. Perhaps a more concrete example would be bind<std::array, int, _1>. I
> *think* that should be easily implementable.
>

Seems reasonable.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkxDvKATjWaJa0f3vHkVAiYCEU%2BS71qVM3_UjYJyz%2Btxw%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 3=
0 January 2017 at 13:48, &#39;Matt Calabrese&#39; via ISO C++ Standard - Fu=
ture Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><span class=3D"">On Mon, Jan 30, 2017 at 3:58 PM,=
 Richard Smith <span dir=3D"ltr">&lt;<a href=3D"mailto:richard@metafoo.co.u=
k" target=3D"_blank">richard@metafoo.co.uk</a>&gt;</span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div cl=
ass=3D"gmail_quote"><div><div class=3D"m_-1991849939707256614m_-64750842714=
88917280h5">On 30 January 2017 at 12:47, &#39;Matt Calabrese&#39; via ISO C=
++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-=
proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span class=
=3D"m_-1991849939707256614m_-6475084271488917280m_-4681168260625194970gmail=
-">On Mon, Jan 30, 2017 at 3:22 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.co=
m</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><d=
iv>Anyway, as someone who&#39;s done a decent amount of C++98/03 metaprogra=
mming, it&#39;s unfortunately no replacement for a language feature. If the=
 complexity of the tricks involved wasn&#39;t already enough, it&#39;s impo=
ssible to make it work consistently with arbitrary template parameter kinds=
 (MPL lambdas live in a world of templates whose only template parameter ki=
nds are types).<br></div></div></div></div></blockquote><div><br></div></sp=
an><div>On that note, though, I recall that James Touton has voiced a desir=
e for an &quot;any-template-parameter-kind&quot; kind (sort of like the new=
 &quot;auto&quot; template parameters, but would match *any* template param=
eter kind). He may even=C2=A0be actively working on such a proposal. That w=
ould at least make a library-level MPL-style lambda facility more capable, =
but still no replacement for something in the language.</div></div></div></=
div></blockquote><div><br></div></div></div><div>Even with such a facility =
(which I think we sorely need), you still presumably couldn&#39;t fully sup=
port non-type template arguments nor packs with a library-only approach: gi=
ven</div><div><br></div><div>=C2=A0 template&lt;int N&gt; struct A {};=C2=
=A0</div><div><br></div><div><div>there&#39;s no way that A&lt;_1&gt; can m=
ean anything other than A&lt;N&gt; for some specific integer N.</div></div>=
</div></div></div></blockquote><div><br></div></span><div>Right, *this* syn=
tax wouldn&#39;t be usable in that case. In those specific kinds of cases y=
ou would use some explicit binding syntax, like bind&lt;A, _1&gt;. Perhaps =
a more concrete example would be bind&lt;std::array, int, _1&gt;. I *think*=
 that should be easily implementable.</div></div></div></div></blockquote><=
div><br></div><div>Seems reasonable.</div></div></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkxDvKATjWaJa0f3vHkVAiYCEU%2BS7=
1qVM3_UjYJyz%2Btxw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkxDvKA=
TjWaJa0f3vHkVAiYCEU%2BS71qVM3_UjYJyz%2Btxw%40mail.gmail.com</a>.<br />

--f403045d606c5456aa0547574ed5--

.


Author: Eric Niebler <eric.niebler@gmail.com>
Date: Mon, 30 Jan 2017 14:30:20 -0800
Raw View
--001a1141c7a25cfc710547575cd6
Content-Type: text/plain; charset=UTF-8

Richard, thanks for replying.

On Mon, Jan 30, 2017 at 11:47 AM, Richard Smith <richard@metafoo.co.uk>
wrote:

> On 30 January 2017 at 10:10, Eric Niebler <eric.niebler@gmail.com> wrote:
>
>> On Mon, Jan 30, 2017 at 9:38 AM, 'Johannes Schaub' via ISO C++ Standard -
>> Future Proposals <std-proposals@isocpp.org> wrote:
>>
>>> 2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
>>> > Crazy thought.
>>> >
>>> > Why not permit template template aliases?
>>> >
>>> >   template <class A>
>>> >   template <class B>
>>> >   using Foo = pair<A, B>;
>>> >
>>> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>>> >
>>> > Why?
>>> >
>>> > Higher order template metaprogramming sometimes requires passing a
>>> template
>>> > to a template. For example:
>>> >
>>> >   // with C++17 fold expressions
>>> >   template <template <class Ts> class Pred, class...Ts>
>>> >   constexpr bool all_of = (... && Pred<Ts>::value);
>>> >
>>> >   static_assert(all_of<std::is_scalar, int, short, float>);
>>> >
>>> > Q: How would you use all_of to check that all types in a pack are
>>> > convertible to bool?
>>> > A: With a "bind"-like template template alias:
>>> >
>>> >   template <template<class...> class Fn, class...As>
>>> >   template <class...Bs>
>>> >   using bind_back = Fn<Bs..., As...>;
>>> >
>>> >   template <template<class...> class Fn>
>>> >   template <class T>
>>> >   using unary = Fn<T>;
>>> >
>>> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>,
>>> int,
>>> > short, float>);
>>> >
>>> > What would this language feature break?
>>> >
>>>
>>> Some note about the syntax. I think you need to extend it so that
>>> "template" can be put after the angle brackets aswell?
>>>
>>>     template<typename T>
>>>     struct A { template<typename A> template<typename B> using X =
>>> void (A::*)(B); };
>>>
>>>     template<typename T>
>>>     void f() {
>>>        typename T::template X<string> template<size_t> p =
>>> &string::resize;
>>>     }
>>>
>>>     int main() { f<A>(); }
>>>
>>> Note the second "template" disambiguator.
>>>
>>
>>
>> Yuk. Or maybe:
>>
>>     template<typename T>
>>     void f() {
>>        typename T::template template X<string><size_t> p =
>> &string::resize;
>>     }
>>
>> Also, yuk. On the plus side, the existence of template template aliases
>> would obviate most of the need to nest a template (template) alias in a
>> struct.
>>
>
> It's probably useful to look at the proposal side-by-side with how we
> might write it today:
>
>   template <template<class...> class Fn, class...As>
>   template <class...Bs>
>   using bind_back = Fn<Bs..., As...>;
>
>   // 'unary' is not required any more, per P0522
>


YAY! :-)



>   static_assert(all_of<bind_back<std::is_convertible, bool>, int, short,
> float>);
>
> vs
>
>   template <template<class...> class Fn, class...As>
>   struct bind_back {
>     template <class...Bs>
>     using apply = Fn<Bs..., As...>;
>   };
>
>   static_assert(all_of<bind_back<std::is_convertible, bool>::template
> apply, int, short, float>);
>
> (with one difference being that template argument deduction can presumably
> look through a curried alias template, but can't look through the class
> template formulation).
>
>
> Another way to get a similar effect would be to allow partial application
> of templates at the point of use instead of allowing currying in the
> definition.
>


Good point!



> So (strawman syntax):
>
>   static_assert(all_of<std::is_convertible<bool, _1>, int, short, float>);
>
> where std::is_convertible<bool, _1> is a type lambda, with the above being
> shorthand for
>
>   template<typename T> using X = std::is_convertible<bool, T>;
>   static_assert(all_of<X, int, short, float>);
>
> (In fact, I think you can implement an _1 and an all_of sufficient to
> support the above as a library, but it would have a lot of limitations.)
>
> Or we could support type lambdas directly (again, strawman syntax):
>
>   static_assert(all_of<[]<typename T> -> std::is_convertible<bool, T>,
> int, short, float>);
>
> These don't quite provide the full power of your curried alias templates,
> though; I don't see a way to get the effect of
>
>   template<typename ...A> template<typename ...B> using X =
> pair<tuple<A...>, tuple<B...>>;
>
> ... since the above alternatives don't provide a way to specify where the
> end of the first pack is. We could perhaps get that effect with another
> extension:
>
>   template<typename ...A, typename ...B> using X = pair<tuple<A...>,
> tuple<B...>>;
>   X<int, char; float> pt; // pair<tuple<int, char>, tuple<float>>
>


Have you guys moved on to the suggestion to add a way to match any template
parameter kind plus the wonky T<a,b; c> syntax? Those are interesting
suggestions, but I'm not yet convinced they're better for the problem at
hand than template template aliases. I'm willing to be convinced otherwise,
though.

Eric

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ephbW949k1sCcYC%3DMLK-gyAR46XM536dq7OGV%3DST0jg%40mail.gmail.com.

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

<div dir=3D"ltr">Richard, thanks for replying.<br><div class=3D"gmail_extra=
"><br><div class=3D"gmail_quote">On Mon, Jan 30, 2017 at 11:47 AM, Richard =
Smith <span dir=3D"ltr">&lt;<a href=3D"mailto:richard@metafoo.co.uk" target=
=3D"_blank">richard@metafoo.co.uk</a>&gt;</span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><div><div class=3D"h5">On 30 January 2017 at 10:10, Eric Niebler=
 <span dir=3D"ltr">&lt;<a href=3D"mailto:eric.niebler@gmail.com" target=3D"=
_blank">eric.niebler@gmail.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><div><div class=3D"m_9008952965704852614gmail-=
h5">On Mon, Jan 30, 2017 at 9:38 AM, &#39;Johannes Schaub&#39; via ISO C++ =
Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-pro=
posals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=3D=
"m_9008952965704852614gmail-m_232073812449960824gmail-HOEnZb"><div class=3D=
"m_9008952965704852614gmail-m_232073812449960824gmail-h5">2017-01-30 18:24 =
GMT+01:00 Eric Niebler &lt;<a href=3D"mailto:eric.niebler@gmail.com" target=
=3D"_blank">eric.niebler@gmail.com</a>&gt;:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;bi<wbr>nd_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
&gt;<br>
<br>
</div></div>Some note about the syntax. I think you need to extend it so th=
at<br>
&quot;template&quot; can be put after the angle brackets aswell?<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 struct A { template&lt;typename A&gt; template&lt;typename B&=
gt; using X =3D<br>
void (A::*)(B); };<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 void f() {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template X&lt;string&gt; template&lt=
;size_t&gt; p =3D &amp;string::resize;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 int main() { f&lt;A&gt;(); }<br>
<br>
Note the second &quot;template&quot; disambiguator.<br></blockquote><div><b=
r></div><div><br></div></div></div><div>Yuk. Or maybe:</div><div><br></div>=
<div><span class=3D"m_9008952965704852614gmail-">=C2=A0 =C2=A0 template&lt;=
typename T&gt;<br>=C2=A0 =C2=A0 void f() {<br></span>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0typename T::template template X&lt;string&gt;&lt;size_t&gt; p =3D &am=
p;string::resize;<br>=C2=A0 =C2=A0 }<br></div><div><br></div><div>Also, yuk=
.. On the plus side, the existence of template template aliases would obviat=
e most of the need to nest a template (template) alias in a struct.</div></=
div></div></div></blockquote><div><br></div></div></div><div>It&#39;s proba=
bly useful to look at the proposal side-by-side with how we might write it =
today:</div><div><br></div><div><span class=3D""><div>=C2=A0 template &lt;t=
emplate&lt;class...&gt; class Fn, class...As&gt;</div><div>=C2=A0 template =
&lt;class...Bs&gt;</div><div>=C2=A0 using bind_back =3D Fn&lt;Bs..., As...&=
gt;;</div><div><br></div></span><div>=C2=A0 // &#39;unary&#39; is not requi=
red any more, per P0522</div></div></div></div></div></blockquote><div><br>=
</div><div><br></div><div>YAY! :-)</div><div><br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><di=
v class=3D"gmail_quote"><div><div>=C2=A0 static_assert(all_of&lt;bind_<wbr>=
back&lt;std::is_convertible, bool&gt;, int, short, float&gt;);</div></div><=
div><br></div><div>vs</div><span class=3D""><div><br></div><div>=C2=A0 temp=
late &lt;template&lt;class...&gt; class Fn, class...As&gt;</div></span><div=
>=C2=A0 struct bind_back {</div><div>=C2=A0 =C2=A0 template &lt;class...Bs&=
gt;</div><div>=C2=A0 =C2=A0 using apply =3D Fn&lt;Bs..., As...&gt;;</div><d=
iv>=C2=A0 };</div><div><br></div><div><div>=C2=A0 static_assert(all_of&lt;b=
ind_<wbr>back&lt;std::is_convertible, bool&gt;::template apply, int, short,=
 float&gt;);</div></div><div><br></div><div>(with one difference being that=
 template argument deduction can presumably look through a curried alias te=
mplate, but can&#39;t look through the class template formulation).</div><d=
iv><br></div><div><br></div><div>Another way to get a similar effect would =
be to allow partial application of templates at the point of use instead of=
 allowing currying in the definition. </div></div></div></div></blockquote>=
<div><br></div><div><br></div><div>Good point!</div><div><br></div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmai=
l_extra"><div class=3D"gmail_quote"><div>So (strawman syntax):</div><div><b=
r></div><div>=C2=A0 static_assert(all_of&lt;std::is_<wbr>convertible&lt;boo=
l, _1&gt;, int, short, float&gt;);<br></div><div><br></div><div>where std::=
is_convertible&lt;bool, _1&gt; is a type lambda, with the above being short=
hand for</div><div><br></div><div>=C2=A0 template&lt;typename T&gt; using X=
 =3D std::is_convertible&lt;bool, T&gt;;</div><div>=C2=A0 static_assert(all=
_of&lt;X, int, short, float&gt;);<br></div><div><br></div><div>(In fact, I =
think you can implement an _1 and an all_of sufficient to support the above=
 as a library, but it would have a lot of limitations.)</div><div><br></div=
><div>Or we could support type lambdas directly (again, strawman syntax):</=
div><div><br></div><div><div>=C2=A0 static_assert(all_of&lt;[]&lt;<wbr>type=
name T&gt; -&gt; std::is_convertible&lt;bool, T&gt;, int, short, float&gt;)=
;</div></div><div><br></div><div><div>These don&#39;t quite provide the ful=
l power of your curried alias templates, though; I don&#39;t see a way to g=
et the effect of</div><div><br></div><div>=C2=A0 template&lt;typename ...A&=
gt; template&lt;typename ...B&gt; using X =3D pair&lt;tuple&lt;A...&gt;, tu=
ple&lt;B...&gt;&gt;;</div><div><br></div><div>... since the above alternati=
ves don&#39;t provide a way to specify where the end of the first pack is. =
We could perhaps get that effect with another extension:</div></div><div><b=
r></div><div>=C2=A0 template&lt;typename ...A, typename ...B&gt; using X =
=3D pair&lt;tuple&lt;A...&gt;, tuple&lt;B...&gt;&gt;;</div><div>=C2=A0 X&lt=
;int, char; float&gt; pt; // pair&lt;tuple&lt;int, char&gt;, tuple&lt;float=
&gt;&gt;</div></div></div></div></blockquote><div><br></div><div><br></div>=
<div>Have you guys moved on to the suggestion to add a way to match any tem=
plate parameter kind plus the wonky T&lt;a,b; c&gt; syntax? Those are inter=
esting suggestions, but I&#39;m not yet convinced they&#39;re better for th=
e problem at hand than template template aliases. I&#39;m willing to be con=
vinced otherwise, though.</div><div><br></div><div>Eric</div><div><br></div=
><div>=C2=A0</div></div><br></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ephbW949k1sCcYC%3DMLK-gyAR46X=
M536dq7OGV%3DST0jg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f9ephbW=
949k1sCcYC%3DMLK-gyAR46XM536dq7OGV%3DST0jg%40mail.gmail.com</a>.<br />

--001a1141c7a25cfc710547575cd6--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 30 Jan 2017 16:06:27 -0800
Raw View
--001a11423f5849b763054758b522
Content-Type: text/plain; charset=UTF-8

On 30 January 2017 at 14:30, Eric Niebler <eric.niebler@gmail.com> wrote:

> Richard, thanks for replying.
>
> On Mon, Jan 30, 2017 at 11:47 AM, Richard Smith <richard@metafoo.co.uk>
> wrote:
>
>> On 30 January 2017 at 10:10, Eric Niebler <eric.niebler@gmail.com> wrote:
>>
>>> On Mon, Jan 30, 2017 at 9:38 AM, 'Johannes Schaub' via ISO C++ Standard
>>> - Future Proposals <std-proposals@isocpp.org> wrote:
>>>
>>>> 2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
>>>> > Crazy thought.
>>>> >
>>>> > Why not permit template template aliases?
>>>> >
>>>> >   template <class A>
>>>> >   template <class B>
>>>> >   using Foo = pair<A, B>;
>>>> >
>>>> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>>>> >
>>>> > Why?
>>>> >
>>>> > Higher order template metaprogramming sometimes requires passing a
>>>> template
>>>> > to a template. For example:
>>>> >
>>>> >   // with C++17 fold expressions
>>>> >   template <template <class Ts> class Pred, class...Ts>
>>>> >   constexpr bool all_of = (... && Pred<Ts>::value);
>>>> >
>>>> >   static_assert(all_of<std::is_scalar, int, short, float>);
>>>> >
>>>> > Q: How would you use all_of to check that all types in a pack are
>>>> > convertible to bool?
>>>> > A: With a "bind"-like template template alias:
>>>> >
>>>> >   template <template<class...> class Fn, class...As>
>>>> >   template <class...Bs>
>>>> >   using bind_back = Fn<Bs..., As...>;
>>>> >
>>>> >   template <template<class...> class Fn>
>>>> >   template <class T>
>>>> >   using unary = Fn<T>;
>>>> >
>>>> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>,
>>>> int,
>>>> > short, float>);
>>>> >
>>>> > What would this language feature break?
>>>> >
>>>>
>>>> Some note about the syntax. I think you need to extend it so that
>>>> "template" can be put after the angle brackets aswell?
>>>>
>>>>     template<typename T>
>>>>     struct A { template<typename A> template<typename B> using X =
>>>> void (A::*)(B); };
>>>>
>>>>     template<typename T>
>>>>     void f() {
>>>>        typename T::template X<string> template<size_t> p =
>>>> &string::resize;
>>>>     }
>>>>
>>>>     int main() { f<A>(); }
>>>>
>>>> Note the second "template" disambiguator.
>>>>
>>>
>>>
>>> Yuk. Or maybe:
>>>
>>>     template<typename T>
>>>     void f() {
>>>        typename T::template template X<string><size_t> p =
>>> &string::resize;
>>>     }
>>>
>>> Also, yuk. On the plus side, the existence of template template aliases
>>> would obviate most of the need to nest a template (template) alias in a
>>> struct.
>>>
>>
>> It's probably useful to look at the proposal side-by-side with how we
>> might write it today:
>>
>>   template <template<class...> class Fn, class...As>
>>   template <class...Bs>
>>   using bind_back = Fn<Bs..., As...>;
>>
>>   // 'unary' is not required any more, per P0522
>>
>
>
> YAY! :-)
>
>
>
>>   static_assert(all_of<bind_back<std::is_convertible, bool>, int, short,
>> float>);
>>
>> vs
>>
>>   template <template<class...> class Fn, class...As>
>>   struct bind_back {
>>     template <class...Bs>
>>     using apply = Fn<Bs..., As...>;
>>   };
>>
>>   static_assert(all_of<bind_back<std::is_convertible, bool>::template
>> apply, int, short, float>);
>>
>> (with one difference being that template argument deduction can
>> presumably look through a curried alias template, but can't look through
>> the class template formulation).
>>
>>
>> Another way to get a similar effect would be to allow partial application
>> of templates at the point of use instead of allowing currying in the
>> definition.
>>
>
>
> Good point!
>
>
>
>> So (strawman syntax):
>>
>>   static_assert(all_of<std::is_convertible<bool, _1>, int, short,
>> float>);
>>
>> where std::is_convertible<bool, _1> is a type lambda, with the above
>> being shorthand for
>>
>>   template<typename T> using X = std::is_convertible<bool, T>;
>>   static_assert(all_of<X, int, short, float>);
>>
>> (In fact, I think you can implement an _1 and an all_of sufficient to
>> support the above as a library, but it would have a lot of limitations.)
>>
>> Or we could support type lambdas directly (again, strawman syntax):
>>
>>   static_assert(all_of<[]<typename T> -> std::is_convertible<bool, T>,
>> int, short, float>);
>>
>> These don't quite provide the full power of your curried alias templates,
>> though; I don't see a way to get the effect of
>>
>>   template<typename ...A> template<typename ...B> using X =
>> pair<tuple<A...>, tuple<B...>>;
>>
>> ... since the above alternatives don't provide a way to specify where the
>> end of the first pack is. We could perhaps get that effect with another
>> extension:
>>
>>   template<typename ...A, typename ...B> using X = pair<tuple<A...>,
>> tuple<B...>>;
>>   X<int, char; float> pt; // pair<tuple<int, char>, tuple<float>>
>>
>
>
> Have you guys moved on to the suggestion to add a way to match any
> template parameter kind plus the wonky T<a,b; c> syntax? Those are
> interesting suggestions, but I'm not yet convinced they're better for the
> problem at hand than template template aliases. I'm willing to be convinced
> otherwise, though.
>

At this point I think we're just exploring the design space.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnSLLFdBN-R6Nk7Jp-JLv%2BRSFvfyTuTo092dnO%2BO1an_Q%40mail.gmail.com.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 3=
0 January 2017 at 14:30, Eric Niebler <span dir=3D"ltr">&lt;<a href=3D"mail=
to:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@gmail.com</a>&gt;=
</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Richard, =
thanks for replying.<br><div class=3D"gmail_extra"><br><div class=3D"gmail_=
quote"><div><div class=3D"h5">On Mon, Jan 30, 2017 at 11:47 AM, Richard Smi=
th <span dir=3D"ltr">&lt;<a href=3D"mailto:richard@metafoo.co.uk" target=3D=
"_blank">richard@metafoo.co.uk</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><div><div class=3D"m_-6145190073583077102h5">On 30 January 2017 a=
t 10:10, Eric Niebler <span dir=3D"ltr">&lt;<a href=3D"mailto:eric.niebler@=
gmail.com" target=3D"_blank">eric.niebler@gmail.com</a>&gt;</span> wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><div><div class=3D"m_-61451=
90073583077102m_9008952965704852614gmail-h5">On Mon, Jan 30, 2017 at 9:38 A=
M, &#39;Johannes Schaub&#39; via ISO C++ Standard - Future Proposals <span =
dir=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isocpp.org" target=3D"_blan=
k">std-proposals@isocpp.org</a>&gt;</span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex"><div class=3D"m_-6145190073583077102m_900895296=
5704852614gmail-m_232073812449960824gmail-HOEnZb"><div class=3D"m_-61451900=
73583077102m_9008952965704852614gmail-m_232073812449960824gmail-h5">2017-01=
-30 18:24 GMT+01:00 Eric Niebler &lt;<a href=3D"mailto:eric.niebler@gmail.c=
om" target=3D"_blank">eric.niebler@gmail.com</a>&gt;:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;bi<wbr>nd_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
&gt;<br>
<br>
</div></div>Some note about the syntax. I think you need to extend it so th=
at<br>
&quot;template&quot; can be put after the angle brackets aswell?<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 struct A { template&lt;typename A&gt; template&lt;typename B&=
gt; using X =3D<br>
void (A::*)(B); };<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 void f() {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template X&lt;string&gt; template&lt=
;size_t&gt; p =3D &amp;string::resize;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 int main() { f&lt;A&gt;(); }<br>
<br>
Note the second &quot;template&quot; disambiguator.<br></blockquote><div><b=
r></div><div><br></div></div></div><div>Yuk. Or maybe:</div><div><br></div>=
<div><span class=3D"m_-6145190073583077102m_9008952965704852614gmail-">=C2=
=A0 =C2=A0 template&lt;typename T&gt;<br>=C2=A0 =C2=A0 void f() {<br></span=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template template X&lt;string&gt;&l=
t;size_t&gt; p =3D &amp;string::resize;<br>=C2=A0 =C2=A0 }<br></div><div><b=
r></div><div>Also, yuk. On the plus side, the existence of template templat=
e aliases would obviate most of the need to nest a template (template) alia=
s in a struct.</div></div></div></div></blockquote><div><br></div></div></d=
iv><div>It&#39;s probably useful to look at the proposal side-by-side with =
how we might write it today:</div><div><br></div><div><span><div>=C2=A0 tem=
plate &lt;template&lt;class...&gt; class Fn, class...As&gt;</div><div>=C2=
=A0 template &lt;class...Bs&gt;</div><div>=C2=A0 using bind_back =3D Fn&lt;=
Bs..., As...&gt;;</div><div><br></div></span><div>=C2=A0 // &#39;unary&#39;=
 is not required any more, per P0522</div></div></div></div></div></blockqu=
ote><div><br></div><div><br></div></div></div><div>YAY! :-)</div><span clas=
s=3D""><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><div=
>=C2=A0 static_assert(all_of&lt;bind_back<wbr>&lt;std::is_convertible, bool=
&gt;, int, short, float&gt;);</div></div><div><br></div><div>vs</div><span>=
<div><br></div><div>=C2=A0 template &lt;template&lt;class...&gt; class Fn, =
class...As&gt;</div></span><div>=C2=A0 struct bind_back {</div><div>=C2=A0 =
=C2=A0 template &lt;class...Bs&gt;</div><div>=C2=A0 =C2=A0 using apply =3D =
Fn&lt;Bs..., As...&gt;;</div><div>=C2=A0 };</div><div><br></div><div><div>=
=C2=A0 static_assert(all_of&lt;bind_back<wbr>&lt;std::is_convertible, bool&=
gt;::template apply, int, short, float&gt;);</div></div><div><br></div><div=
>(with one difference being that template argument deduction can presumably=
 look through a curried alias template, but can&#39;t look through the clas=
s template formulation).</div><div><br></div><div><br></div><div>Another wa=
y to get a similar effect would be to allow partial application of template=
s at the point of use instead of allowing currying in the definition. </div=
></div></div></div></blockquote><div><br></div><div><br></div></span><div>G=
ood point!</div><span class=3D""><div><br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>So (strawman syntax):</div><div><br></div><div>=C2=A0=
 static_assert(all_of&lt;std::is_c<wbr>onvertible&lt;bool, _1&gt;, int, sho=
rt, float&gt;);<br></div><div><br></div><div>where std::is_convertible&lt;b=
ool, _1&gt; is a type lambda, with the above being shorthand for</div><div>=
<br></div><div>=C2=A0 template&lt;typename T&gt; using X =3D std::is_conver=
tible&lt;bool, T&gt;;</div><div>=C2=A0 static_assert(all_of&lt;X, int, shor=
t, float&gt;);<br></div><div><br></div><div>(In fact, I think you can imple=
ment an _1 and an all_of sufficient to support the above as a library, but =
it would have a lot of limitations.)</div><div><br></div><div>Or we could s=
upport type lambdas directly (again, strawman syntax):</div><div><br></div>=
<div><div>=C2=A0 static_assert(all_of&lt;[]&lt;typena<wbr>me T&gt; -&gt; st=
d::is_convertible&lt;bool, T&gt;, int, short, float&gt;);</div></div><div><=
br></div><div><div>These don&#39;t quite provide the full power of your cur=
ried alias templates, though; I don&#39;t see a way to get the effect of</d=
iv><div><br></div><div>=C2=A0 template&lt;typename ...A&gt; template&lt;typ=
ename ...B&gt; using X =3D pair&lt;tuple&lt;A...&gt;, tuple&lt;B...&gt;&gt;=
;</div><div><br></div><div>... since the above alternatives don&#39;t provi=
de a way to specify where the end of the first pack is. We could perhaps ge=
t that effect with another extension:</div></div><div><br></div><div>=C2=A0=
 template&lt;typename ...A, typename ...B&gt; using X =3D pair&lt;tuple&lt;=
A...&gt;, tuple&lt;B...&gt;&gt;;</div><div>=C2=A0 X&lt;int, char; float&gt;=
 pt; // pair&lt;tuple&lt;int, char&gt;, tuple&lt;float&gt;&gt;</div></div><=
/div></div></blockquote><div><br></div><div><br></div></span><div>Have you =
guys moved on to the suggestion to add a way to match any template paramete=
r kind plus the wonky T&lt;a,b; c&gt; syntax? Those are interesting suggest=
ions, but I&#39;m not yet convinced they&#39;re better for the problem at h=
and than template template aliases. I&#39;m willing to be convinced otherwi=
se, though.</div></div></div></div></blockquote><div><br></div><div>At this=
 point I think we&#39;re just exploring the design space.=C2=A0</div></div>=
</div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnSLLFdBN-R6Nk7Jp-JLv%2BRSFvfyT=
uTo092dnO%2BO1an_Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnSLLFd=
BN-R6Nk7Jp-JLv%2BRSFvfyTuTo092dnO%2BO1an_Q%40mail.gmail.com</a>.<br />

--001a11423f5849b763054758b522--

.


Author: Eric Niebler <eric.niebler@gmail.com>
Date: Wed, 1 Feb 2017 14:40:25 -0800
Raw View
--94eb2c18e65424ad5c05477fbc3f
Content-Type: text/plain; charset=UTF-8

On Mon, Jan 30, 2017 at 4:06 PM, Richard Smith <richard@metafoo.co.uk>
wrote:

> On 30 January 2017 at 14:30, Eric Niebler <eric.niebler@gmail.com> wrote:
>
>> Richard, thanks for replying.
>>
>> On Mon, Jan 30, 2017 at 11:47 AM, Richard Smith <richard@metafoo.co.uk>
>> wrote:
>>
>>> On 30 January 2017 at 10:10, Eric Niebler <eric.niebler@gmail.com>
>>> wrote:
>>>
>>>> On Mon, Jan 30, 2017 at 9:38 AM, 'Johannes Schaub' via ISO C++ Standard
>>>> - Future Proposals <std-proposals@isocpp.org> wrote:
>>>>
>>>>> 2017-01-30 18:24 GMT+01:00 Eric Niebler <eric.niebler@gmail.com>:
>>>>> > Crazy thought.
>>>>> >
>>>>> > Why not permit template template aliases?
>>>>> >
>>>>> >   template <class A>
>>>>> >   template <class B>
>>>>> >   using Foo = pair<A, B>;
>>>>> >
>>>>> > Foo<A> is a unary template such that Foo<A><B> is pair<A,B>.
>>>>> >
>>>>> > Why?
>>>>> >
>>>>> > Higher order template metaprogramming sometimes requires passing a
>>>>> template
>>>>> > to a template. For example:
>>>>> >
>>>>> >   // with C++17 fold expressions
>>>>> >   template <template <class Ts> class Pred, class...Ts>
>>>>> >   constexpr bool all_of = (... && Pred<Ts>::value);
>>>>> >
>>>>> >   static_assert(all_of<std::is_scalar, int, short, float>);
>>>>> >
>>>>> > Q: How would you use all_of to check that all types in a pack are
>>>>> > convertible to bool?
>>>>> > A: With a "bind"-like template template alias:
>>>>> >
>>>>> >   template <template<class...> class Fn, class...As>
>>>>> >   template <class...Bs>
>>>>> >   using bind_back = Fn<Bs..., As...>;
>>>>> >
>>>>> >   template <template<class...> class Fn>
>>>>> >   template <class T>
>>>>> >   using unary = Fn<T>;
>>>>> >
>>>>> >   static_assert(all_of<unary<bind_back<std::is_convertible, bool>>,
>>>>> int,
>>>>> > short, float>);
>>>>> >
>>>>> > What would this language feature break?
>>>>> >
>>>>>
>>>>> Some note about the syntax. I think you need to extend it so that
>>>>> "template" can be put after the angle brackets aswell?
>>>>>
>>>>>     template<typename T>
>>>>>     struct A { template<typename A> template<typename B> using X =
>>>>> void (A::*)(B); };
>>>>>
>>>>>     template<typename T>
>>>>>     void f() {
>>>>>        typename T::template X<string> template<size_t> p =
>>>>> &string::resize;
>>>>>     }
>>>>>
>>>>>     int main() { f<A>(); }
>>>>>
>>>>> Note the second "template" disambiguator.
>>>>>
>>>>
>>>>
>>>> Yuk. Or maybe:
>>>>
>>>>     template<typename T>
>>>>     void f() {
>>>>        typename T::template template X<string><size_t> p =
>>>> &string::resize;
>>>>     }
>>>>
>>>> Also, yuk. On the plus side, the existence of template template aliases
>>>> would obviate most of the need to nest a template (template) alias in a
>>>> struct.
>>>>
>>>
>>> It's probably useful to look at the proposal side-by-side with how we
>>> might write it today:
>>>
>>>   template <template<class...> class Fn, class...As>
>>>   template <class...Bs>
>>>   using bind_back = Fn<Bs..., As...>;
>>>
>>>   // 'unary' is not required any more, per P0522
>>>
>>
>>
>> YAY! :-)
>>
>>
>>
>>>   static_assert(all_of<bind_back<std::is_convertible, bool>, int,
>>> short, float>);
>>>
>>> vs
>>>
>>>   template <template<class...> class Fn, class...As>
>>>   struct bind_back {
>>>     template <class...Bs>
>>>     using apply = Fn<Bs..., As...>;
>>>   };
>>>
>>>   static_assert(all_of<bind_back<std::is_convertible, bool>::template
>>> apply, int, short, float>);
>>>
>>> (with one difference being that template argument deduction can
>>> presumably look through a curried alias template, but can't look through
>>> the class template formulation).
>>>
>>>
>>> Another way to get a similar effect would be to allow partial
>>> application of templates at the point of use instead of allowing currying
>>> in the definition.
>>>
>>
>>
>> Good point!
>>
>>
>>
>>> So (strawman syntax):
>>>
>>>   static_assert(all_of<std::is_convertible<bool, _1>, int, short,
>>> float>);
>>>
>>> where std::is_convertible<bool, _1> is a type lambda, with the above
>>> being shorthand for
>>>
>>>   template<typename T> using X = std::is_convertible<bool, T>;
>>>   static_assert(all_of<X, int, short, float>);
>>>
>>> (In fact, I think you can implement an _1 and an all_of sufficient to
>>> support the above as a library, but it would have a lot of limitations.)
>>>
>>> Or we could support type lambdas directly (again, strawman syntax):
>>>
>>>   static_assert(all_of<[]<typename T> -> std::is_convertible<bool, T>,
>>> int, short, float>);
>>>
>>> These don't quite provide the full power of your curried alias
>>> templates, though; I don't see a way to get the effect of
>>>
>>>   template<typename ...A> template<typename ...B> using X =
>>> pair<tuple<A...>, tuple<B...>>;
>>>
>>> ... since the above alternatives don't provide a way to specify where
>>> the end of the first pack is. We could perhaps get that effect with another
>>> extension:
>>>
>>>   template<typename ...A, typename ...B> using X = pair<tuple<A...>,
>>> tuple<B...>>;
>>>   X<int, char; float> pt; // pair<tuple<int, char>, tuple<float>>
>>>
>>
>>
>> Have you guys moved on to the suggestion to add a way to match any
>> template parameter kind plus the wonky T<a,b; c> syntax? Those are
>> interesting suggestions, but I'm not yet convinced they're better for the
>> problem at hand than template template aliases. I'm willing to be convinced
>> otherwise, though.
>>
>
> At this point I think we're just exploring the design space.
>


The exploration seems to have petered out. Going back to my original
suggestion, I have two questions.

1. Does supporting template template aliases (maybe with "template
template" as a syntactic disambiguator, as in T::template template A<a><b>)
introduce implementation difficulties?
2. Does someone who knows the core language want to write a paper with me
(for some meeting *after* Kona)?

Bonus:
Does some compiler implementor want to take a stab at implementing this?
*cough* Richard *cough*

Thanks,
Eric

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f_XfMV5yBNuGs-Wt4KnKEvk0CTNFg4AiYMpWWvy%3D1ZqKg%40mail.gmail.com.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Jan 30, 2017 at 4:06 PM, Richard Smith <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co=
..uk</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><div class=3D"=
h5">On 30 January 2017 at 14:30, Eric Niebler <span dir=3D"ltr">&lt;<a href=
=3D"mailto:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@gmail.com=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">R=
ichard, thanks for replying.<br><div class=3D"gmail_extra"><br><div class=
=3D"gmail_quote"><div><div class=3D"m_9054604621584202397h5">On Mon, Jan 30=
, 2017 at 11:47 AM, Richard Smith <span dir=3D"ltr">&lt;<a href=3D"mailto:r=
ichard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt;</span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"g=
mail_extra"><div class=3D"gmail_quote"><div><div class=3D"m_905460462158420=
2397m_-6145190073583077102h5">On 30 January 2017 at 10:10, Eric Niebler <sp=
an dir=3D"ltr">&lt;<a href=3D"mailto:eric.niebler@gmail.com" target=3D"_bla=
nk">eric.niebler@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote"><div><div class=3D"m_9054604621584202397m_-614519007=
3583077102m_9008952965704852614gmail-h5">On Mon, Jan 30, 2017 at 9:38 AM, &=
#39;Johannes Schaub&#39; via ISO C++ Standard - Future Proposals <span dir=
=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">=
std-proposals@isocpp.org</a>&gt;</span> wrote:<br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex"><div class=3D"m_9054604621584202397m_-614519007358=
3077102m_9008952965704852614gmail-m_232073812449960824gmail-HOEnZb"><div cl=
ass=3D"m_9054604621584202397m_-6145190073583077102m_9008952965704852614gmai=
l-m_232073812449960824gmail-h5">2017-01-30 18:24 GMT+01:00 Eric Niebler &lt=
;<a href=3D"mailto:eric.niebler@gmail.com" target=3D"_blank">eric.niebler@g=
mail.com</a>&gt;:<br>
&gt; Crazy thought.<br>
&gt;<br>
&gt; Why not permit template template aliases?<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class A&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class B&gt;<br>
&gt;=C2=A0 =C2=A0using Foo =3D pair&lt;A, B&gt;;<br>
&gt;<br>
&gt; Foo&lt;A&gt; is a unary template such that Foo&lt;A&gt;&lt;B&gt; is pa=
ir&lt;A,B&gt;.<br>
&gt;<br>
&gt; Why?<br>
&gt;<br>
&gt; Higher order template metaprogramming sometimes requires passing a tem=
plate<br>
&gt; to a template. For example:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0// with C++17 fold expressions<br>
&gt;=C2=A0 =C2=A0template &lt;template &lt;class Ts&gt; class Pred, class..=
..Ts&gt;<br>
&gt;=C2=A0 =C2=A0constexpr bool all_of =3D (... &amp;&amp; Pred&lt;Ts&gt;::=
value);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;std::is_<wbr>scalar, int, short, f=
loat&gt;);<br>
&gt;<br>
&gt; Q: How would you use all_of to check that all types in a pack are<br>
&gt; convertible to bool?<br>
&gt; A: With a &quot;bind&quot;-like template template alias:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn, class...As=
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class...Bs&gt;<br>
&gt;=C2=A0 =C2=A0using bind_back =3D Fn&lt;Bs..., As...&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;template&lt;class...&gt; class Fn&gt;<br>
&gt;=C2=A0 =C2=A0template &lt;class T&gt;<br>
&gt;=C2=A0 =C2=A0using unary =3D Fn&lt;T&gt;;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0static_assert(all_of&lt;unary&lt;bi<wbr>nd_back&lt;std::is=
_convertible, bool&gt;&gt;, int,<br>
&gt; short, float&gt;);<br>
&gt;<br>
&gt; What would this language feature break?<br>
&gt;<br>
<br>
</div></div>Some note about the syntax. I think you need to extend it so th=
at<br>
&quot;template&quot; can be put after the angle brackets aswell?<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 struct A { template&lt;typename A&gt; template&lt;typename B&=
gt; using X =3D<br>
void (A::*)(B); };<br>
<br>
=C2=A0 =C2=A0 template&lt;typename T&gt;<br>
=C2=A0 =C2=A0 void f() {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template X&lt;string&gt; template&lt=
;size_t&gt; p =3D &amp;string::resize;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 int main() { f&lt;A&gt;(); }<br>
<br>
Note the second &quot;template&quot; disambiguator.<br></blockquote><div><b=
r></div><div><br></div></div></div><div>Yuk. Or maybe:</div><div><br></div>=
<div><span class=3D"m_9054604621584202397m_-6145190073583077102m_9008952965=
704852614gmail-">=C2=A0 =C2=A0 template&lt;typename T&gt;<br>=C2=A0 =C2=A0 =
void f() {<br></span>=C2=A0 =C2=A0 =C2=A0 =C2=A0typename T::template templa=
te X&lt;string&gt;&lt;size_t&gt; p =3D &amp;string::resize;<br>=C2=A0 =C2=
=A0 }<br></div><div><br></div><div>Also, yuk. On the plus side, the existen=
ce of template template aliases would obviate most of the need to nest a te=
mplate (template) alias in a struct.</div></div></div></div></blockquote><d=
iv><br></div></div></div><div>It&#39;s probably useful to look at the propo=
sal side-by-side with how we might write it today:</div><div><br></div><div=
><span><div>=C2=A0 template &lt;template&lt;class...&gt; class Fn, class...=
As&gt;</div><div>=C2=A0 template &lt;class...Bs&gt;</div><div>=C2=A0 using =
bind_back =3D Fn&lt;Bs..., As...&gt;;</div><div><br></div></span><div>=C2=
=A0 // &#39;unary&#39; is not required any more, per P0522</div></div></div=
></div></div></blockquote><div><br></div><div><br></div></div></div><div>YA=
Y! :-)</div><span><div><br></div><div>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><div><div>=C2=A0 static_assert(all_of&lt;bind_back<wbr>&lt;std::is_conver=
tible, bool&gt;, int, short, float&gt;);</div></div><div><br></div><div>vs<=
/div><span><div><br></div><div>=C2=A0 template &lt;template&lt;class...&gt;=
 class Fn, class...As&gt;</div></span><div>=C2=A0 struct bind_back {</div><=
div>=C2=A0 =C2=A0 template &lt;class...Bs&gt;</div><div>=C2=A0 =C2=A0 using=
 apply =3D Fn&lt;Bs..., As...&gt;;</div><div>=C2=A0 };</div><div><br></div>=
<div><div>=C2=A0 static_assert(all_of&lt;bind_back<wbr>&lt;std::is_converti=
ble, bool&gt;::template apply, int, short, float&gt;);</div></div><div><br>=
</div><div>(with one difference being that template argument deduction can =
presumably look through a curried alias template, but can&#39;t look throug=
h the class template formulation).</div><div><br></div><div><br></div><div>=
Another way to get a similar effect would be to allow partial application o=
f templates at the point of use instead of allowing currying in the definit=
ion. </div></div></div></div></blockquote><div><br></div><div><br></div></s=
pan><div>Good point!</div><span><div><br></div><div>=C2=A0</div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>So (strawman syntax):</div><div><br></div><div>=C2=A0=
 static_assert(all_of&lt;std::is_c<wbr>onvertible&lt;bool, _1&gt;, int, sho=
rt, float&gt;);<br></div><div><br></div><div>where std::is_convertible&lt;b=
ool, _1&gt; is a type lambda, with the above being shorthand for</div><div>=
<br></div><div>=C2=A0 template&lt;typename T&gt; using X =3D std::is_conver=
tible&lt;bool, T&gt;;</div><div>=C2=A0 static_assert(all_of&lt;X, int, shor=
t, float&gt;);<br></div><div><br></div><div>(In fact, I think you can imple=
ment an _1 and an all_of sufficient to support the above as a library, but =
it would have a lot of limitations.)</div><div><br></div><div>Or we could s=
upport type lambdas directly (again, strawman syntax):</div><div><br></div>=
<div><div>=C2=A0 static_assert(all_of&lt;[]&lt;typena<wbr>me T&gt; -&gt; st=
d::is_convertible&lt;bool, T&gt;, int, short, float&gt;);</div></div><div><=
br></div><div><div>These don&#39;t quite provide the full power of your cur=
ried alias templates, though; I don&#39;t see a way to get the effect of</d=
iv><div><br></div><div>=C2=A0 template&lt;typename ...A&gt; template&lt;typ=
ename ...B&gt; using X =3D pair&lt;tuple&lt;A...&gt;, tuple&lt;B...&gt;&gt;=
;</div><div><br></div><div>... since the above alternatives don&#39;t provi=
de a way to specify where the end of the first pack is. We could perhaps ge=
t that effect with another extension:</div></div><div><br></div><div>=C2=A0=
 template&lt;typename ...A, typename ...B&gt; using X =3D pair&lt;tuple&lt;=
A...&gt;, tuple&lt;B...&gt;&gt;;</div><div>=C2=A0 X&lt;int, char; float&gt;=
 pt; // pair&lt;tuple&lt;int, char&gt;, tuple&lt;float&gt;&gt;</div></div><=
/div></div></blockquote><div><br></div><div><br></div></span><div>Have you =
guys moved on to the suggestion to add a way to match any template paramete=
r kind plus the wonky T&lt;a,b; c&gt; syntax? Those are interesting suggest=
ions, but I&#39;m not yet convinced they&#39;re better for the problem at h=
and than template template aliases. I&#39;m willing to be convinced otherwi=
se, though.</div></div></div></div></blockquote><div><br></div></div></div>=
<div>At this point I think we&#39;re just exploring the design space.=C2=A0=
</div></div></div></div></blockquote><div><br></div><div><br></div><div>The=
 exploration seems to have petered out. Going back to my original suggestio=
n, I have two questions.</div><div><br></div><div>1. Does supporting templa=
te template aliases (maybe with &quot;template template&quot; as a syntacti=
c disambiguator, as in T::template template A&lt;a&gt;&lt;b&gt;) introduce =
implementation difficulties?</div><div>2. Does someone who knows the core l=
anguage want to write a paper with me (for some meeting *after* Kona)?</div=
><div><br></div><div>Bonus:</div><div>Does some compiler implementor want t=
o take a stab at implementing this? *cough* Richard *cough*</div><div><br><=
/div><div>Thanks,</div><div>Eric</div><div><br></div><div>=C2=A0</div></div=
><br></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAAvM5f_XfMV5yBNuGs-Wt4KnKEvk0CTNFg4A=
iYMpWWvy%3D1ZqKg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAAvM5f_XfMV5yB=
NuGs-Wt4KnKEvk0CTNFg4AiYMpWWvy%3D1ZqKg%40mail.gmail.com</a>.<br />

--94eb2c18e65424ad5c05477fbc3f--

.


Author: David Stone <deusexsophismata@gmail.com>
Date: Thu, 2 Feb 2017 18:55:40 -0800 (PST)
Raw View
------=_Part_1491_186793585.1486090540885
Content-Type: multipart/alternative;
 boundary="----=_Part_1492_1830184067.1486090540885"

------=_Part_1492_1830184067.1486090540885
Content-Type: text/plain; charset=UTF-8

Another solution to the same problem would be to use "normal" functions /
function objects and use something like boost::hana to convert the types to
values. Then existing language features can be used (with better syntax in
many cases). Instead of thing<int><int>, you would use
thing(type<int>)(type<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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b2f08945-41e8-4992-b13a-826d7c0a796a%40isocpp.org.

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

<div dir=3D"ltr">Another solution to the same problem would be to use &quot=
;normal&quot; functions / function objects and use something like boost::ha=
na to convert the types to values. Then existing language features can be u=
sed (with better syntax in many cases). Instead of thing&lt;int&gt;&lt;int&=
gt;, you would use thing(type&lt;int&gt;)(type&lt;int&gt;).<br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b2f08945-41e8-4992-b13a-826d7c0a796a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b2f08945-41e8-4992-b13a-826d7c0a796a=
%40isocpp.org</a>.<br />

------=_Part_1492_1830184067.1486090540885--

------=_Part_1491_186793585.1486090540885--

.