Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does not a template template parameter allow 'typename' after the parameter list

Template template typename?

When using template template syntax as in template <template <typename> class T>, it is required to use the keyword class, as using typename gives an error along the lines of:

error: template template parameter requires 'class' after the parameter list

Everywhere else the keywords typename and class are interchangeable in the basic case of declaring a template parameter.

You could argue that the requirement when using template template is a hint that you are expected to pass a class type, but this is not always the case (especially not after C++11 introduced templated type aliases).

template <template <typename> class T> // 'class' keyword required. struct Foo {     using type = T<int>; };  template <typename T> using type = T (*)();  using func_ptr_t = Foo<type>::type; 

What is the reasoning behind this?

  • Is there any specific reason as to why typename is not allowed in template template declarations?
  • Does the C++ standard say anything about this?
like image 236
Felix Glas Avatar asked Jun 06 '14 12:06

Felix Glas


People also ask

What is typename in template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

Can a template be a template parameter?

Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.

What is the difference between template typename T and template T?

There is no difference. typename and class are interchangeable in the declaration of a type template parameter.


2 Answers

Short answer: because the Standard says so.

Longer answer: prior to Standardization, C++ templates required the class keyword for all template parameters. However, to stress the fact that templates could also be of non-class (i.e. builtin) type, an alternative keyword typename was introduced. However, in C++98, template-template parameters could only be of class-type, and this was the reason that the typename keyword was not added in that context.

Enter C++11 and its new feature template aliases, that now also introduced non-class templates, and hence non-class template-template parameters:

template<typename T> struct A {}; template<typename T> using B = int;  template<template<typename> class X> struct C; C<A> ca; // ok C<B> cb; // ok, not a class template template<template<typename> typename X> struct D; // error, cannot use typename here 

The above example was taken from the current C++1z proposal N4051 titled Allow typename in a template template parameter, and proposes to allow precisely that.

Clang 3.5 SVN now supports this with the -std=c++1z flag.

like image 82
TemplateRex Avatar answered Sep 24 '22 10:09

TemplateRex


I'm looking for the rational behind this restriction [...]

Before C++11 was introduced, the only templates you could pass to a template template parameter were class templates. That's why the use of the keyword class was enforced. Additionally, the keyword typename implies that the template parameter is a substitution for an arbitrary type and not a template, so using typename in that context would just blur the line between the names of types and (class) templates. That's comprehensible.

Nowadays, such arguments can be the names of class templates or alias templates, and since those aren't even remotely connected, the enforcement of the keyword class is more or less obsolete. The proposal N4051 opts to change this with C++1Z.

like image 30
Columbo Avatar answered Sep 23 '22 10:09

Columbo