220 8416 <-5123564187529511709@gmail297201516> article
Path: news.gmane.org!not-for-mail
From: Richard Smith <metafoo@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: A new keyword for either a type or a variable
 (typical use case for variadic template template)?
Date: Tue, 07 Jan 2014 02:17:33 +0000
Lines: 238
Approved: news@gmane.org
Message-ID: <-5123564187529511709@gmail297201516>
References: <f4ec2cca-5951-447f-a938-0b2e5e3e233f@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=047d7b343b50aabdbb04ef57fa9d
X-Trace: ger.gmane.org 1389061049 18113 80.91.229.3 (7 Jan 2014 02:17:29 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Tue, 7 Jan 2014 02:17:29 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDI4T64VSQPRBPWHVWLAKGQEUT5H4OY@isocpp.org Tue Jan 07 03:17:36 2014
Return-path: <std-proposals+bncBDI4T64VSQPRBPWHVWLAKGQEUT5H4OY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-oa0-f69.google.com ([209.85.219.69])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDI4T64VSQPRBPWHVWLAKGQEUT5H4OY@isocpp.org>)
	id 1W0MEZ-0002Q8-L0
	for gclcip-std-proposals@m.gmane.org; Tue, 07 Jan 2014 03:17:35 +0100
Original-Received: by mail-oa0-f69.google.com with SMTP id m1sf10980534oag.0
        for <gclcip-std-proposals@m.gmane.org>; Mon, 06 Jan 2014 18:17:34 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:references:from:date:message-id
         :subject:to:x-original-sender:x-original-authentication-results
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe:content-type;
        bh=g7O83qeELudOoauznFs5PKJeq8IzkyMK6Ei8Z5jePgU=;
        b=dv3FoXnHNQOMWT6bZtEN2j87BmsEF6aP9Kwn2unD+HhMffyTpMmQGBm7ISzYy0DsdN
         awi1H2khJPUP6E5bxO/7jUXBySkD/3d5iCFffCvK6Y+F40pksGzQXbQqtEJ/4juWr+IP
         FuIFL4vnzwKW5feW6tBUnhcKRsnIePbiNJ04Gg+oXc7wLXZ3a8LacEYWBc3U20CpYAPs
         EI+9OPg/AYthUBsA/JwLJVjk77yLnL2CklvEvf8u+DoGH1g612u2dp0ErfLaQlq1iK/A
         MsRQVeoMUWx9fLDM2cO7Fta5qbi3xLkGqY4otc95xkUZnOjJ4Lt/FYd179H9vigHXx36
         nISw==
X-Gm-Message-State: ALoCoQnzT4wwfOo5mDrqSYogFIyjlOAaZQAjHPkDn0RW2Mzeut0kJvusku/oq6H1G7AKbi+jKuVP
X-Received: by 10.182.104.70 with SMTP id gc6mr3642318obb.35.1389061054648;
        Mon, 06 Jan 2014 18:17:34 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.25.196 with SMTP id e4ls5858096qeg.6.gmail; Mon, 06 Jan
 2014 18:17:33 -0800 (PST)
X-Received: by 10.49.2.170 with SMTP id 10mr193044122qev.24.1389061053966;
        Mon, 06 Jan 2014 18:17:33 -0800 (PST)
Original-Received: from mail-vb0-x22f.google.com (mail-vb0-x22f.google.com [2607:f8b0:400c:c02::22f])
        by mx.google.com with ESMTPS id 10si871212qai.93.2014.01.06.18.17.33
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Mon, 06 Jan 2014 18:17:33 -0800 (PST)
Received-SPF: pass (google.com: domain of metafoo@gmail.com designates 2607:f8b0:400c:c02::22f as permitted sender) client-ip=2607:f8b0:400c:c02::22f;
Original-Received: by mail-vb0-f47.google.com with SMTP id m10so3374331vbh.20
        for <std-proposals@isocpp.org>; Mon, 06 Jan 2014 18:17:33 -0800 (PST)
X-Received: by 10.220.104.84 with SMTP id n20mr5045445vco.8.1389061053527;
 Mon, 06 Jan 2014 18:17:33 -0800 (PST)
X-Original-Sender: metafoo@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of metafoo@gmail.com designates 2607:f8b0:400c:c02::22f as permitted
 sender) smtp.mail=metafoo@gmail.com;       dkim=pass header.i=@gmail.com;
       dmarc=pass (p=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: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:8416
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/8416>

--047d7b343b50aabdbb04ef57fa9d
Content-Type: text/plain; charset=ISO-8859-1

On Tue Dec 24 2013 at 3:33:27 PM, Vincent Reverdy <vince.rev@gmail.com>
wrote:

> Hi,
>
> Currently, it is impossible, as far as I know, to write a "
> is_specialization_of" helper struct to detect whether a type is a
> specialization of a given template.
> It can be illustrated with the following example:
> ----------------------------------------------------------------------
> #include <iostream>
> #include <type_traits>
> #include <tuple>
> #include <vector>
> #include <array>
>
> template <template <class...> class Template, class T>
> struct is_specialization_of
> : std::false_type {};
>
> template <template <class...> class Template, class... Args>
> struct is_specialization_of<Template, Template<Args...>>
> : std::true_type {};
>
> int main()
> {
>     std::cout<<is_specialization_of<std::tuple,
> std::tuple<double>>::value<<::std::endl;
>     std::cout<<is_specialization_of<std::vector,
> std::tuple<double>>::value<<::std::endl;
>     std::cout<<is_specialization_of<std::array,
> std::tuple<double>>::value<<::std::endl; // Error
>     return 0;
> }
> ----------------------------------------------------------------------
> It works well for templates of the form template <class...> but it fails
> for mixed type/variable template like std::array.
> I think that it would be great (particularly for template metaprogramming)
> to have a a new keyword (whose name has to be defined) to declare "a type
> or a variable".
> With this new keyword, one could type:
> ----------------------------------------------------------------------
> #include <iostream>
> #include <type_traits>
> #include <tuple>
> #include <vector>
> #include <array>
>
> template <template <keyword...> class Template, class T>
> struct is_specialization_of
> : std::false_type {};
>
> template <template <keyword...> class Template, keyword... Args>
> struct is_specialization_of<Template, Template<keyword...>>
> : std::true_type {};
>
> int main()
> {
>     std::cout<<is_specialization_of<std::tuple,
> std::tuple<double>>::value<<::std::endl;
>     std::cout<<is_specialization_of<std::vector,
> std::tuple<double>>::value<<::std::endl;
>     std::cout<<is_specialization_of<std::array,
> std::tuple<double>>::value<<::std::endl; // Ok
>     return 0;
> }
> ----------------------------------------------------------------------
>
> Has it been already discussed?
> If not, what is you opinion about such a thing?
> If yes, what were the issues?
> Do you have any suggestion for the name of this keyword?
>

This seems like a useful addition to me, though perhaps we can get by
without introducing a new keyword. I think there was a paper on exactly
this, probably by Mike Spertus, either in 2012 or 2013, but the WG21 papers
site seems to be down at the moment so I can't easily check.

One issue springs to mind: the injected-class-name of a class template can
be used as a template template argument or as a type template argument:

template<template<typename> class> struct A {};
template<typename> struct B {};
template<typename T> struct C {
  A<C> a; // ok, pass template C
  B<C> b; // ok, pass type C<T>
};

I suppose we could (and probably should) preserve this behavior when 'C' is
passed through such a template argument, but it's a weird corner case that
you'll need to handle somehow.

Rather than introducing a new keyword, you could use a '?' token:

  template<template<? ...> class A, ? ... Ts> void f(A<Ts...>);

(or a '*' token, or something similar).

The 'auto' keyword would make sense here, but it might make more sense
being restricted to a non-type template parameter (with its type deduced
from the template argument). Perhaps it could be made to fill both roles:

  template<auto X> void f() {
    int a = X; // it's a value by default
  }
  template<auto X> void g() {
    typename X y; // it can be explicitly treated as a type
  }
  template<auto X> void h() {
    template X<int> z; // or as a template
  }
  template<auto &X> void i(); // not exactly 'auto', always a non-type
template parameter

.... though this would require a lot of hacking with the grammar, to allow
'template' and 'typename' in these new places.

-- 

--- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7b343b50aabdbb04ef57fa9d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>On Tue Dec 24 2013 at 3:33:27 PM, Vincent Reverdy &lt;<a href=3D"mailt=
o:vince.rev@gmail.com">vince.rev@gmail.com</a>&gt; wrote:</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex">
<div dir=3D"ltr">Hi, <br><br>Currently, it is impossible, as far as I know,=
 to write a &quot;<span style=3D"font-family:courier new,monospace">is_spec=
ialization_of</span>&quot; helper struct to detect whether a type is a spec=
ialization of a given template.<br>
It can be illustrated with the following example:<br><span style=3D"font-fa=
mily:courier new,monospace">-----------------------------------------------=
-----------------------</span><br><span style=3D"font-family:courier new,mo=
nospace">#include &lt;iostream&gt;<br>
#include &lt;type_traits&gt;<br>#include &lt;tuple&gt;<br>#include &lt;vect=
or&gt;<br>#include &lt;array&gt;<br><br>template &lt;template &lt;class...&=
gt; class Template, class T&gt;<br>struct is_specialization_of <br>: std::f=
alse_type {};<br>
=A0<br>template &lt;template &lt;class...&gt; class Template, class... Args=
&gt;<br>struct is_specialization_of&lt;Template, Template&lt;Args...&gt;&gt=
; <br>: std::true_type {};<br><br>int main()<br>{<br>=A0=A0=A0 std::cout&lt=
;&lt;is_specialization_of&lt;std::tuple,=A0 std::tuple&lt;double&gt;&gt;::v=
alue&lt;&lt;::std::endl;<br>
=A0=A0=A0 std::cout&lt;&lt;is_specialization_of&lt;std::vector, std::tuple&=
lt;double&gt;&gt;::value&lt;&lt;::std::endl;<br>=A0=A0=A0 std::cout&lt;&lt;=
is_specialization_of&lt;std::array,=A0 std::tuple&lt;double&gt;&gt;::value&=
lt;&lt;::std::endl; // Error<br>
=A0=A0=A0 return 0;<br>}</span><br><span style=3D"font-family:courier new,m=
onospace">-----------------------------------------------------------------=
-----</span><br>It works well for templates of the form <span style=3D"font=
-family:courier new,monospace">template &lt;class...&gt;</span> but it fail=
s for mixed type/variable template like <span style=3D"font-family:courier =
new,monospace">std::array</span>.<br>
I think that it would be great (particularly for template metaprogramming) =
to have a a new keyword (whose name has to be defined) to declare &quot;a t=
ype or a variable&quot;.<br>With this new keyword, one could type:<br><span=
 style=3D"font-family:courier new,monospace">------------------------------=
----------------------------------------</span><br>
<span style=3D"font-family:courier new,monospace">#include &lt;iostream&gt;=
<br>#include &lt;type_traits&gt;<br>#include &lt;tuple&gt;<br>#include &lt;=
vector&gt;<br>#include &lt;array&gt;<br><br>template &lt;template &lt;keywo=
rd...&gt; class Template, class T&gt;<br>
struct is_specialization_of <br>: std::false_type {};<br>=A0<br>template &l=
t;template &lt;keyword...&gt; class Template, keyword... Args&gt;<br>struct=
 is_specialization_of&lt;Template, Template&lt;keyword...&gt;&gt; <br>: std=
::true_type {};<br>
<br>int main()<br>{<br>=A0=A0=A0 std::cout&lt;&lt;is_specialization_of&lt;s=
td::tuple,=A0 std::tuple&lt;double&gt;&gt;::value&lt;&lt;::std::endl;<br>=
=A0=A0=A0 std::cout&lt;&lt;is_specialization_of&lt;std::vector, std::tuple&=
lt;double&gt;&gt;::value&lt;&lt;::std::endl;<br>
=A0=A0=A0 std::cout&lt;&lt;is_specialization_of&lt;std::array,=A0 std::tupl=
e&lt;double&gt;&gt;::value&lt;&lt;::std::endl; // Ok<br>=A0=A0=A0 return 0;=
<br>}</span><br><span style=3D"font-family:courier new,monospace">---------=
-------------------------------------------------------------</span><br>
<br>Has it been already discussed? <br>If not, what is you opinion about su=
ch a thing?<br>If yes, what were the issues?<br>Do you have any suggestion =
for the name of this keyword?</div></blockquote><div><br></div><div>This se=
ems like a useful addition to me, though perhaps we can get by without intr=
oducing a new keyword. I think there was a paper on exactly this, probably =
by Mike Spertus, either in 2012 or 2013, but the WG21 papers site seems to =
be down at the moment so I can&#39;t easily check.</div>
<div><br></div><div>One issue springs to mind: the injected-class-name of a=
 class template can be used as a template template argument or as a type te=
mplate argument:</div><div><br></div><div>template&lt;template&lt;typename&=
gt; class&gt; struct A {};</div>
<div>template&lt;typename&gt; struct B {};</div><div>template&lt;typename T=
&gt; struct C {</div><div>=A0 A&lt;C&gt; a; // ok, pass template C</div><di=
v>=A0 B&lt;C&gt; b; // ok, pass type C&lt;T&gt;</div><div>};</div><div><br>
</div><div>I suppose we could (and probably should) preserve this behavior =
when &#39;C&#39; is passed through such a template argument, but it&#39;s a=
 weird corner case that you&#39;ll need to handle somehow.</div><div><br>
</div><div>Rather than introducing a new keyword, you could use a &#39;?&#3=
9; token:</div><div><br></div><div>=A0 template&lt;template&lt;? ...&gt; cl=
ass A, ? ... Ts&gt; void f(A&lt;Ts...&gt;);</div><div><br></div><div>(or a =
&#39;*&#39; token, or something similar).</div>
<div><br></div><div>The &#39;auto&#39; keyword would make sense here, but i=
t might make more sense being restricted to a non-type template parameter (=
with its type deduced from the template argument). Perhaps it could be made=
 to fill both roles:</div>
<div><br></div><div>=A0 template&lt;auto X&gt; void f() {</div><div>=A0 =A0=
 int a =3D X; // it&#39;s a value by default<br></div><div>=A0 }</div><div>=
=A0 template&lt;auto X&gt; void g() {</div><div>=A0 =A0 typename X y; // it=
 can be explicitly treated as a type</div>
<div>=A0 }</div><div>=A0 template&lt;auto X&gt; void h() {</div><div>=A0 =
=A0 template X&lt;int&gt; z; // or as a template</div><div>=A0 }</div><div>=
=A0 template&lt;auto &amp;X&gt; void i(); // not exactly &#39;auto&#39;, al=
ways a non-type template parameter</div>
<div><br></div><div>... though this would require a lot of hacking with the=
 grammar, to allow &#39;template&#39; and &#39;typename&#39; in these new p=
laces.</div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b343b50aabdbb04ef57fa9d--

.
