Можно ли сгенерировать линейную иерархию из параметров вариационного шаблона? Например:
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;
Спасибо 🙂
Я не думаю, что вы можете позволить 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 {};