Topic: Specializing a template template-parameters with a template template class.


Author: itaj sherman <itajsherman@gmail.com>
Date: Thu, 10 Mar 2011 07:21:45 CST
Raw View
Has the standard ever considered the option of defining template of
template of class?

Why should it not be possible to define:
template< typename T1, typename T2 > template< typename U1, typename
U2, typename U3 > class Y {};
Y is a template with 2 parameters of a template with 3 parameters of a
class.
Which would make X< A, B > a template class with 3 parameters.

The natural transform to:
template< typename T1, typename T2, typename U1, typename U2, typename
U3 > class X {};
is not equivalent in c++ with respect to partial specialization.

The problem was raised in this thread in comp.lang.c++, but with no
much resolution to this particular issue.
http://groups.google.com/group/comp.lang.c++/browse_frm/thread/e5f4456dd3182753#

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.

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.

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

itaj


--
[ 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                      ]





Author: Noah Roberts <noneed@toemailme.com>
Date: Sat, 12 Mar 2011 09:26:40 CST
Raw View
In article <472cc17b-b5ee-4897-81e7-
c52fe1b228ad@a11g2000pro.googlegroups.com>, itajsherman@gmail.com
says...

> 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.
>
> 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.
>
> Has this ever been considered as a c++ feature?
>
> itaj


In the new standard you'll be able to use template aliases and your
unworkable attempt to work around the non-existence of such will no
longer be an issue.

--
http://crazycpp.wordpress.com/


[ 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                      ]





Author: itaj sherman <itajsherman@gmail.com>
Date: Sun, 13 Mar 2011 09:55:59 CST
Raw View
On Mar 12, 5:26 pm, Noah Roberts <non...@toemailme.com> wrote:

>
> In the new standard you'll be able to use template aliases and your
> unworkable attempt to work around the non-existence of such will no
> longer be an issue.
>

I don't see how the template aliases would solve this by themelves.
How would you define that specialization of A?

itaj


--
[ 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                      ]





Author: Richard Smith<metafoo@gmail.com>
Date: Wed, 27 Apr 2011 10:54:22 CST
Raw View
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                      ]