Question

Is it possible to generate a linear hierarchy from variadic template parameters? For example:

GenLinearHierarchy<A,B,C,D,...> linHierarchy;

Generates a hierarchy where A -> B -> C -> D -> ... -> Empty (where the -> symbol stands for inherits from).

Where the template parameters (template template... parameters) have signatures such as:

template <class Base, class Plate> class A;

Where Base is the class above A in the hierarchy and Plate is the 'most derived' class (for example D< E<...>, A<...> >).

So far I've been unsuccessful - starting to wonder whether I'm going in circles (I do keep running into cyclic problems).

Sorry about the confusion - here is a 'concrete solution' (one which I'm not too fond of):

// Linear Hierarchy

#include <iostream>

template <class Base, class Floor>
class D : public Base
{
public:
};

template <class Base, class Floor>
class C : public Base
{
public:
        void Fire()
        {
                static_cast<Floor*>(this)->Handle();
        }
};

template <class Base, class Floor>
class B : public Base
{
public:
        void Handle()
        {
                std::cout << "Handled" << std::endl;
        }
};

class _FINISH {};

class _START : public B<C<D<_FINISH, _START>, _START, _START> {};

int main()
{
        typedef _START A;
        A a;
        a.Fire();

        return 0;
}

So, I'm still looking for a 'GenLinearHierarchy' class which can generate something like above, but with an instatiation like this:

GenLinearHierarchy<B,C,D> linHierarchy;

Thanks :)

Was it helpful?

Solution

I don't think you can let Plate be the most derived type, as that would mean the overall type would have to have itself as one of its own template parameters. This is the closest I've gotten:

struct Empty {};

template <template <class> class Head, template <class> class... Tail>
struct GenLinearHierarchy
{
    typedef Head<typename GenLinearHierarchy<Tail...>::type> type;
};

template <template <class> class Tail>
struct GenLinearHierarchy<Tail>
{
    typedef Tail<Empty> type;
};

template <class Base> struct A : Base {};
template <class Base> struct B : Base {};
template <class Base> struct C : Base {};
template <class Base> struct D : Base {};

static_assert(std::is_same< typename GenLinearHierarchy<A,B,C,D>::type
                          , A<B<C<D<Empty>>>>                          >::value
             , "");

EDIT I think I've got what you wished for. Good luck trying to read it. You've only got yourself to blame. :)

struct Empty {};

template <class MostDerived,
          template <class, class> class Head,
          template <class, class> class... Tail>
struct GenLinearHierarchyInner
{
    typedef Head<typename GenLinearHierarchyInner<MostDerived,
                                                  Tail...>::type,
                 MostDerived> type;
};

template <class MostDerived,
          template <class, class> class Tail>
struct GenLinearHierarchyInner<MostDerived, Tail>
{
    typedef Tail<Empty, MostDerived> type;
};

template <template <class, class> class... Types>
struct GenLinearHierarchy : GenLinearHierarchyInner<GenLinearHierarchy<Types...>,
                                                    Types...>::type
{};

template <class Base, class> struct A : Base {};
template <class Base, class> struct B : Base {};
template <class Base, class> struct C : Base {};
template <class Base, class> struct D : Base {};

typedef GenLinearHierarchy<A,B,C,D> ABCD;

static_assert(std::is_base_of< A<B<C<D<Empty, ABCD>, ABCD>, ABCD>, ABCD>
                             , ABCD                                      >::value
             , "");

OTHER TIPS

It's probably something like this...

template<typename T, typename... Args>
class GenLinearHierarchy : public T, public GenLinearHierarchy<Args...> {};

template<typename T>
class GenLinearHierarchy<T> : public T {};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top