220 30708 <CAAvM5f9ephbW949k1sCcYC=MLK-gyAR46XM536dq7OGV=ST0jg@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Eric Niebler <eric.niebler@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: template template aliases?
Date: Mon, 30 Jan 2017 14:30:20 -0800
Lines: 350
Approved: news@gmane.org
Message-ID: <CAAvM5f9ephbW949k1sCcYC=MLK-gyAR46XM536dq7OGV=ST0jg@mail.gmail.com>
References: <CAAvM5f8JOZqCzNwB3iKqD_wBACVL_j4EA95MbWR_yr1M=R7HbA@mail.gmail.com>
 <CANu6V4U0GDA5Zoi7Ri-fvBp+eM05gXYawQghu69MGTkdS3=91Q@mail.gmail.com>
 <CAAvM5f9ZZ6U-kPcrUBaZfjCH25urYwdM4OesLR61op9uEi4dJw@mail.gmail.com> <CAOfiQqmkNy3vXhTmx6YmQ5StNOjo02TTDBh=SCQ_tNfoqkrhvQ@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=001a1141c7a25cfc710547575cd6
X-Trace: blaine.gmane.org 1485815424 11245 195.159.176.226 (30 Jan 2017 22:30:24 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 30 Jan 2017 22:30:24 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCF3H2GUZUFRB7P4X3CAKGQET4K7B2A@isocpp.org Mon Jan 30 23:30:17 2017
Return-path: <std-proposals+bncBCF3H2GUZUFRB7P4X3CAKGQET4K7B2A@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-oi0-f69.google.com ([209.85.218.69])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCF3H2GUZUFRB7P4X3CAKGQET4K7B2A@isocpp.org>)
	id 1cYKSm-0002am-Ne
	for gclcip-std-proposals@m.gmane.org; Mon, 30 Jan 2017 23:30:17 +0100
Original-Received: by mail-oi0-f69.google.com with SMTP id y140sf383807713oie.2
        for <gclcip-std-proposals@m.gmane.org>; Mon, 30 Jan 2017 14:30:22 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=OZE3BIMym3Dk425REUwnGdqSqPqCDwodOvyGmgIXYcQ=;
        b=qzWs9Hoc02XFKdFPLdK0K6VshRO+hi72D78DzRx3T5sa9ie3b4Z8qh/DnTvixNSeQl
         86enjKS6jE/kYjSN1zvHVDpNLEdw7Zllg3DvEjwLAQWL64XNYmTi5YTxBLNASgC+U0fy
         fH3RFUF1Lsqo5OsB0qu3Wi8PylbKwQE5BZ9TWWSiT1Bx8YDC7h3FI8tahDgrOxCmPWG8
         Ozh9rLUocxfZ0GBdhvDbX0vKcDrREe/eE3aTjAsWHSgM3xLWUu57bW7Kk3EldOYLzmj8
         syBoOZL/5/U0o9Jsww5yj6tylf8cZACSrtsw2TWfb78wCIMl7FZItXgEp1v/qFlVHi+G
         YNZA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=OZE3BIMym3Dk425REUwnGdqSqPqCDwodOvyGmgIXYcQ=;
        b=Q53EMX/KGSVutAI0GG8yD3eqnkSdE5ypeHyNIz3T6/TH2JpcNp4MtsW7cMlcejH2zD
         7hUUUwui9rd/vGkZxmeUqY+oY4pkETzSDLEVBu6hU67EksZws2vhVB2N1Idlbush7P0/
         axVhkiwfSkg6lNe75xI11Y4kkl6ESwnO1J2mYVpF2XV27TGMBubAQRu2jI6jV3bj0UrM
         /KTJ+BZzFqjiaj9C85z/VdwEU9OwS6m1q3fr18BtgbMJWGr7rvDBsR0MhosjoE2XGf5B
         6iEmZkRh5m3BputTxfHxgJDAL2VzPbsvpHzAsO5YCn4aMRFuIDjLDGWPa6NURAOEekl+
         iYOw==
X-Gm-Message-State: AIkVDXIRb+Agl6FB1q3kqbxS79HSNvw2kqPVIs5siX2DE1eW0d0SQ21/jx6t/m+LmHixDw==
X-Received: by 10.157.50.139 with SMTP id u11mr6639302otb.90.1485815422015;
        Mon, 30 Jan 2017 14:30:22 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.52.248 with SMTP id t53ls8891658otd.42.gmail; Mon, 30 Jan
 2017 14:30:21 -0800 (PST)
X-Received: by 10.159.38.131 with SMTP id 3mr10227658uay.59.1485815421338;
        Mon, 30 Jan 2017 14:30:21 -0800 (PST)
Original-Received: from mail-vk0-x22c.google.com (mail-vk0-x22c.google.com. [2607:f8b0:400c:c05::22c])
        by mx.google.com with ESMTPS id 7si4211805uaz.80.2017.01.30.14.30.21
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 30 Jan 2017 14:30:21 -0800 (PST)
Received-SPF: pass (google.com: domain of eric.niebler@gmail.com designates 2607:f8b0:400c:c05::22c as permitted sender) client-ip=2607:f8b0:400c:c05::22c;
Original-Received: by mail-vk0-x22c.google.com with SMTP id k127so225282699vke.0
        for <std-proposals@isocpp.org>; Mon, 30 Jan 2017 14:30:21 -0800 (PST)
X-Received: by 10.31.154.145 with SMTP id c139mr11584924vke.118.1485815420875;
 Mon, 30 Jan 2017 14:30:20 -0800 (PST)
Original-Received: by 10.103.104.133 with HTTP; Mon, 30 Jan 2017 14:30:20 -0800 (PST)
In-Reply-To: <CAOfiQqmkNy3vXhTmx6YmQ5StNOjo02TTDBh=SCQ_tNfoqkrhvQ@mail.gmail.com>
X-Original-Sender: eric.niebler@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com;       spf=pass (google.com: domain of
 eric.niebler@gmail.com designates 2607:f8b0:400c:c05::22c as permitted
 sender) smtp.mailfrom=eric.niebler@gmail.com;       dmarc=pass (p=NONE
 sp=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:30708
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30708>

--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--

.
