Reputation: 890
Consider the following code, that defines an alias template to be passed as an template template parameter:
template<template<class T> class SomeFoo>
class Base {};
template<class T, class Bar>
class Foo {};
class Bar;
template<class T>
using BarFoo = Foo<T, Bar>;
class Bar : public Base<BarFoo> {};
This works as expected. However, if Bar
itself is a template, this solution is not possible, as the alias template depends on the concrete instantiation of Bar
. Defining the alias template inside of Bar
doesn't help either, as it is not yet available when the base class is given. As it seems not to be possible to define the alias template "on the fly" in the parameter list, the only work around I could come up with is to pass Bar
to Base
and define the alias template there:
template<template<class T, class Derived> class SomeFooTL, class Derived>
class Base
{
template<class T>
using SomeFoo = SomeFooTL<T, Derived>;
};
template<class T, class Bar>
class Foo {};
template<class S>
class Bar : public Base<Foo, Bar<S>> {};
This is, however, very unsatisfying, as there could be (and are) other Foo
's that do not depend on anything but T
and now are forced to take an unnecessary second template parameter.
Does anyone know a better way to achieve this?
Upvotes: 2
Views: 98
Reputation: 217293
If I understand correctly what you want, you need an helper, and using a not obvious syntax:
template<template<class> class>
class Base {};
template<class, class>
class Foo {};
template <typename> class Bar;
template <typename S> struct UsingHelper {
template <typename T>
using BarFoo = Foo<T, Bar<S>>;
};
template <typename S>
class Bar : public Base<UsingHelper<S>::template BarFoo> {};
template
is needed in UsingHelper<S>::template BarFoo
as it is a dependent context, and it would be "interpreted" as value instead without. (it is similar to typename my_class<T>::type
, but BarFoo
is a template, not a type.)
Upvotes: 2
Reputation: 10880
Instead of:
template<template<class T> class SomeFoo>
class Base {};
You might want:
template<class SomeFooT>
class Base {};
And use SomeFooT::type<T>
as a template:
struct BarFooT {
template<typename T>
using type = ...;
};
Then you can predeclare struct BarFooT;
.
Upvotes: 0