Knoep
Knoep

Reputation: 890

Passing alias template to base class of a template it depends on

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

Answers (2)

Jarod42
Jarod42

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

lorro
lorro

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

Related Questions