In
template <template <class X> class T>
The template type parameter X
is not a template parameter to the outermost template: it is a template parameter to the innermost template. It's rather similar to
int foo(int (*bar)(int x))
{
int y = x; // compiler error
}
which doesn't work since the function takes a single argument, bar
: there is no argument x
.
Depending upon what you are truly trying to do, you could add the second template parameter, with something like
template <typename X, template <typename> class T >
struct Bar
{
// ...
};
you can keep the declaration with a single type parameter, but pattern match to give a partial specialization that would define the class in the example context
template <typename T>
struct Bar;
template <typename X, template <typename> class T >
struct Bar<T<X>>
{
// ...
};
you could modify Foo
to have a useful nested type, and grab it that way
template <typename T>
struct Bar
{
using X = T::value_type;
};
or you could define a metafunction that extracts a template parameter from a template type, and get it that way:
template <typename T>
struct Bar
{
using X = get_parameter<T>;
};
The most flexible is the last version, except rather than a metafunction that extracts template arguments, you would declare a get_bar_parameter
function, and define a partial specialization that extracts the template parameter from a Foo<X>
(or a T<X>
). That way, if you ever decide in the future to use Bar
with classes where the right value of X
isn't computed that way, you can do so by giving an appropriate specialization for get_bar_parameter
.