Reputation: 1801
I want to specialize the type parameter of the following template class, which has a type parameter and a template template parameter:
template <
typename T,
template <typename E> class Foo
> class Bar;
I tried every permutation of adding and/or omitting .template
and typename
in the last line of each of the following snippets, and none compiles:
1.)
template <
template <typename E> class Foo
> class Bar<int, Foo<typename E>>;
2.)
template <
template <typename E> class Foo
> class Bar<int, Foo.template <typename E>>;
3.)
template <
template <typename E> class Foo
> class Bar<int, Foo<E>>;
4.)
template <
template <typename E> class Foo
class Bar<int, Foo.template <E>>;
Why doesn't any of them work?
Regarding the last line of each applicable snippet:
typename
clarify E
is a type used by class Foo
, or can this syntax only be used within the {}
body of Bar
's class definition?template
clarify Foo
is a template and therefore prevent the compiler from parsing Foo <
as Foo
"is less than", or can this syntax only be used within the {}
body of Bar
's class definition?How can I get this to work?
Upvotes: 1
Views: 193
Reputation: 96790
Doesn't
typename
clarifyE
is a type used by classFoo
, or can this syntax only be used within the{}
body ofBar
's class definition?
typename
is only used when you are defining a type within a template definition (class
could also be used) or when you are accessing a dependent type (a type that depends on a template parameter).
For more information (even about when template
is used) see this thread.
How can I get this to work?
The name of a of a type within template template parameter can't actually be used. It's just there as a formality. You have to add another template parameter to your main template instead:
template <
template<typename> class Foo,
typename E
> class Bar<int, Foo<E>> { ... };
Moreover, if this is a specialization of the template Bar
, then Bar
needs a primary template to specialize:
template<typename T, typename U>
struct Bar;
template <
template<typename> class Foo,
typename E
> class Bar<int, Foo<E>> { ... };
Upvotes: 3
Reputation: 476940
Like this:
template <template <typename E> class Foo>
class Bar<int, Foo>
{
// ...
};
You can even omit the inner parameter name E
, since it serves no purpose.
Upvotes: 1