Параметры шаблонов C++ Variadic для линейной иерархии

Можно ли сгенерировать линейную иерархию из параметров вариационного шаблона? Например:

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

Создает иерархию, в которой A -> B -> C -> D -> ... -> Пусто (где символ -> обозначает наследование).

Где параметры шаблона (шаблон шаблона... параметры) имеют подписи, такие как:

template <class Base, class Plate> class A;

Где Base - это класс выше A в иерархии, а Plate - "наиболее производный" класс (например, D, A<...>>).

До сих пор у меня ничего не получалось - я начинаю задумываться, езжу ли я кругами (я продолжаю сталкиваться с циклическими проблемами).

Извините за путаницу - вот "конкретное решение" (которое мне не особо нравится):

// 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;
}

Итак, я все еще ищу класс 'GenLinearHierarchy', который может генерировать что-то вроде выше, но с установкой как это:

GenLinearHierarchy<B,C,D> linHierarchy;

Спасибо:)

2 ответа

Решение

Я не думаю, что вы можете позволить Plate быть самым производным типом, так как это будет означать, что общий тип должен иметь себя в качестве одного из своих собственных параметров шаблона. Это самое близкое, что я получил:

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
             , "");

РЕДАКТИРОВАТЬ Я думаю, что я получил то, что вы хотели. Удачи в попытке прочитать это. Вы сами виноваты.:)

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
             , "");

Это, наверное, что-то вроде этого...

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

template<typename T>
class GenLinearHierarchy<T> : public T {};
Другие вопросы по тегам