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

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

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

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

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

template <class Base, class Plate> class A;

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

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

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

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

Спасибо 🙂

1

Решение

Я не думаю, что вы можете позволить 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
, "");
1

Другие решения

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

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

template<typename T>
class GenLinearHierarchy<T> : public T {};
0

По вопросам рекламы [email protected]