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;
typename
is not allowed in template template declarations?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.