Topic: Template template arguments


Author: James Kanze <james.kanze@gmail.com>
Date: Thu, 25 Dec 2008 13:18:20 CST
Raw View
On Dec 25, 7:26 am, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:

> One thing that has been bothering me for a while when working
> with templates is that in a template template argument list we
> have to use the keyword 'class' while I prefer 'typename'
> (since it think that it better explains the intention).

Well, typename certainly wouldn't express the intention, since
what is required is a class template.

> Consider the following (legal) declaration:

>  template<template<typename T> class C>
>  void foo(C<int> c);

> And the following (illegal) declaration:

>  template<template<typename T> typename C>
>  void foo(C<int> c);

And what should that mean?  That you can only instantiate it on
something defined as:

   template< typename T >
   typename C ...

?

Please don't take offense (I know from your frequent
contributions that you are really very competent), but have you
really thought this through.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                  Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <Erik-wikstrom@telia.com>
Date: Fri, 26 Dec 2008 21:44:32 CST
Raw View
On 2008-12-25 20:18, James Kanze wrote:
> On Dec 25, 7:26 am, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:
>
>> One thing that has been bothering me for a while when working
>> with templates is that in a template template argument list we
>> have to use the keyword 'class' while I prefer 'typename'
>> (since it think that it better explains the intention).
>
> Well, typename certainly wouldn't express the intention, since
> what is required is a class template.

I would say that we need a type which itself is a template, the fact
that it can only happen if it is a class is, in a way, irrelevant.

>> Consider the following (legal) declaration:
>
>>  template<template<typename T> class C>
>>  void foo(C<int> c);
>
>> And the following (illegal) declaration:
>
>>  template<template<typename T> typename C>
>>  void foo(C<int> c);
>
> And what should that mean?  That you can only instantiate it on
> something defined as:
>
>    template< typename T >
>    typename C ...

The way I read a template declaration is that 'typename' and 'class'
indicates that the following identifier is the name of a type (and
indeed, this is also how 'typename' is use in other places). If we go by
your reasoning, that the usage of 'class' means that the type must be of
class type, then we would not be able to instantiate the following with
a non-class type:

 template<class T>
 T bar(T& t);

So my point is that if we do treat 'typename' and 'class' differently in
this case it is inconsistent to do so in the case I outlined above.

(Actually I do not like the fact that we can use 'class' in template
declarations at all, but that is something I'll have to live with.)

--
Erik Wikstr   m


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@mac.com>
Date: Sat, 27 Dec 2008 15:27:51 CST
Raw View
On Dec 26, 10:44 pm, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:
> On 2008-12-25 20:18, James Kanze wrote:
>
> > On Dec 25, 7:26 am, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:
>
> >> One thing that has been bothering me for a while when working
> >> with templates is that in a template template argument list we
> >> have to use the keyword 'class' while I prefer 'typename'
> >> (since it think that it better explains the intention).
>
> > Well, typename certainly wouldn't express the intention, since
> > what is required is a class template.
>
> I would say that we need a type which itself is a template, the fact
> that it can only happen if it is a class is, in a way, irrelevant.

No, the required parameter is a class template (not a class). And
class templates may not be declared with the "typename" keyword. For
example:

   template <typename T>
   typename C {}; // Error

   template <typename T>
   class C {}; // OK

So, a better question would be why "struct" cannot be used in place of
"class" in this context. That is, why:

      template< template<typename T> struct C>
      void foo(C<int> c);

is not legal C++.

Greg




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Sat, 27 Dec 2008 15:28:28 CST
Raw View
On Dec 27, 4:44 am, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:
> On 2008-12-25 20:18, James Kanze wrote:

> > On Dec 25, 7:26 am, Erik Wikstr   m <Erik-wikst...@telia.com> wrote:

> >> One thing that has been bothering me for a while when
> >> working with templates is that in a template template
> >> argument list we have to use the keyword 'class' while I
> >> prefer 'typename' (since it think that it better explains
> >> the intention).

> > Well, typename certainly wouldn't express the intention,
> > since what is required is a class template.

> I would say that we need a type which itself is a template,
> the fact that it can only happen if it is a class is, in a
> way, irrelevant.

But that's wrong.  The argument is NOT a type; it is a template.
Templates are not types.  What the parameter syntax does is give
more or less a schema for the template.  And since you can't use
typename when declaring a template, you can't use it when
declaring a template template parameter.

> >> Consider the following (legal) declaration:

> >>  template<template<typename T> class C>
> >>  void foo(C<int> c);

> >> And the following (illegal) declaration:

> >>  template<template<typename T> typename C>
> >>  void foo(C<int> c);

> > And what should that mean?  That you can only instantiate it on
> > something defined as:

> >    template< typename T >
> >    typename C ...

> The way I read a template declaration is that 'typename' and
> 'class' indicates that the following identifier is the name of
> a type (and indeed, this is also how 'typename' is use in
> other places).

Exactly.

> If we go by your reasoning, that the usage of 'class' means
> that the type must be of class type, then we would not be able
> to instantiate the following with a non-class type:
>
>  template<class T> T bar(T& t);

No.  That might make sense, but that's not the way it works (for
historical reasons, as I pointed out).

> So my point is that if we do treat 'typename' and 'class'
> differently in this case it is inconsistent to do so in the
> case I outlined above.

In the case you outlined, the language doesn't allow typename in
the non-template case, so it doesn't make sense to allow it in
the template case.  What doesn't make sense is that struct and
union aren't allowed in this context.  I can legally write:
     template< typename T > class X ;
or
     template< typename T > struct X ;
except when this template declaration is used as a parameter for
a template; then only the first form is legal.

> (Actually I do not like the fact that we can use 'class' in
> template declarations at all, but that is something I'll have
> to live with.)

It's historical.  For type parameters, I would say that it
should be avoided, and considered as only something to support
legacy code.

But of course, there are other contexts.  For example:
     template< int (*pf)( class T* ) >
is legal for a non-type parameter.  For that matter, I think
that:
     template< class T* pt >
is also legal for a non-type parameter; at least I can't find
anything off hand to forbid it.  (But I wouldn't use it, and I
wouldn't be surprised if a lot of compilers got it wrong.)

(If this use sounds silly: suppose you are working under Posix,
and you want to have a pointer to the struct stat as a template
parameter.  Of course, I'd probably write:
     template< struct ::stat* pState >
, but logically, replacing class with struct should work.)

What I'd recommend as general programming guidelines is that
each template parameter start with either typename, template or
the name of a type---if it is necessary to use a class keyword
to name the type (e.g. as in the case of ::stat, above), then
use struct.  And never start a template parameter with "class".
Those are my guidelines, though; reasonable people may differ.

And of course, in the parameter (after the first word, which
determines whether it is a non-type, type or template
parameter), the usual parameter syntax holds; typename and class
are NOT synonyms, and each has its use (but struct and class are
synonyms---except in a template parameter, where for some
unknown reason, struct is forbidden).

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <Erik-wikstrom@telia.com>
Date: Thu, 25 Dec 2008 00:26:57 CST
Raw View
Hello, and merry Christmas

One thing that has been bothering me for a while when working with
templates is that in a template template argument list we have to use
the keyword 'class' while I prefer 'typename' (since it think that it
better explains the intention).

Consider the following (legal) declaration:

 template<template<typename T> class C>
 void foo(C<int> c);

And the following (illegal) declaration:

 template<template<typename T> typename C>
 void foo(C<int> c);


While I have not studied the standard in detail I can only find this
requirement in the grammar (Annex A.12):

 template < template-parameter-list > class identifieropt
 template < template-parameter-list > class identifieropt =
   id-expression

And I was wondering why there is no 'typename' version of these lines,
like so:

 template < template-parameter-list > typename identifieropt
 template < template-parameter-list > typename identifieropt =
   id-expression

Can someone give a good explanation of why only the 'class' version is
allowed?

--
Erik Wikstr   m


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]