From -3504224610436976580
X-Google-Thread: f78e5,e1019ee5aaa65968
X-Google-NewGroupId: yes
X-Google-Attributes: gid7894ca11fe,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news2.google.com!news2.google.com!news.glorb.com!news.alt.net
From: Richard Smith<metafoo@gmail.com>
Newsgroups: comp.std.c++
Subject: Re: Specializing a template template-parameters with a template   template class.
Date: Wed, 27 Apr 2011 10:54:22 CST
Organization: http://groups.google.com
Lines: 103
Sender: std-cpp-request@vandevoorde.com
Approved: stephen.clamage@oracle.com
Message-ID: <f246a763-4c0b-45d0-b37c-ac4a0549c9e4@z31g2000vbs.googlegroups.com>
References: <472cc17b-b5ee-4897-81e7-c52fe1b228ad@a11g2000pro.googlegroups.com>
Content-Type: text/plain; charset=ISO-8859-1
To: undisclosed-recipients:;
Return-Path: <cppmods@mcgurn.dreamhost.com>
X-Original-Date: Wed, 27 Apr 2011 07:30:45 -0700 (PDT)
X-Submission-Address: std-c++-submit@vandevoorde.com
Xref: g2news2.google.com comp.std.c++:3275


On Mar 10, 2:21 pm, itaj sherman<itajsher...@gmail.com>  wrote:
>  Has the standard ever considered the option of defining template of
>  template of class?
[...]
>  To demonstrate the problem:
>
>  template<  template<  typename T>  class>  class A;
>  class B {};
>
>  template<  typename T, typename U>  class X {};
>  //and hypothetic equivalent:
>  template<  typename T>  template<  typename U>  class Y {};
>  //or
>  template<  typename T>  template<  typename U>  using Y = X<  T, U>;
>
>  Using the above hypothetical syntax, Y and X could be considered
>  equivalent X<  T, U>  == Y<  T><  U>.
>  However, for any type T, Y<T>  is a template class (with 1 parameter),
>  and it might make sense to be able to specialize the first parameter
>  of A on Y<T>:
>
>  //hypothetically specialize:
>  template<  typename T>  class A<  Y<T>  >  {};
>  //instanciated by A<  Y<B>  >
>
>  With X it's not possible to do such specialization.

There's a caveat here: template arguments for template template
parameters always refer to template declarations, and aren't the same
even if the two declarations are equivalent. If the above were
allowed, 'equivalent' alias template template specializations would
naturally, by extension, refer to different alias templates. Given:

template<typename T>  template<typename U>  using Z = X<T, U>;

Y<B>  and Z<B>  would be different templates, so the partial
specialization for A<Y<B>>  would not match the template specialization
A<Z<B>>, so X and Y would not really be equivalent-up-to-currying in
the desired sense. [Up until FDIS, the working draft contained this
example:

   template<template<class>  class TT>  struct X { };
   template<class>  struct Y { };
   template<class T>  using Z = Y<T>;
   X<Y>  y;
   X<Z>  z;
   declares y and z to be of the same type.

... which, if it weren't wrong, would imply that templates are
compared by alpha-beta-eta equivalence (rather than by name), and that
Y and Z above would be equivalent. I consider it unfortunate that the
example was changed, rather than the normative wording!]

>  Nesting cannot solve that either:
>
>  template<  typename T>  class Z
>  {
>    public: template<  typename U>  class R {};
>
>  };
>
>  template<  typename T>  class A<  Z<T>::R>  {};
>  //cannot instanciate by A<  Z<B>::R>
>
>  It's not possible to deduce T in a member template class Z<T>::R.

Right; a nested name specifier is a non-deduced context. Alias
templates, as per the FDIS, don't help here, since they don't change
this rule.

>  Has this ever been considered as a c++ feature?

I've been implementing support for alias templates in the clang
compiler, and run across this limitation while building testcases for
the feature. I've certainly considered proposing template templates as
an extension for C++1x. As well as covering the deduction case, this
change would have additional benefits:

  * Alias templates would gain the full computational power of the
simply-typed lambda calculus (plus variadic types, but I think those
can always be desugared into plain STLC). [Hence alias template
expansion is still guaranteed to terminate.]

  * It would become simpler to express multiple variadic template
parameter lists for a template:

template<typename... A>  template<typename... B>  struct S;
S<int, char><double, bool, S<><>>  s;

or

template<typename... A>  template<A... B>  struct Tuple;
--
Richard


-- 
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]



