Как стать автором
Обновить

Комментарии 4

boost::mpl::inherit не предполагается задействовать?
Тогда можно автоматизировать создание списка баз.
template<class... Bases> struct derived : boost::mpl::inherit<Bases...>::type
{
	typedef boost::mpl::vector<Bases...> types;
};

class A {.....};
class B {.....};
class C {.....};

class Derived : public derived<A,B,C> {.....};
В проекте у базовых структур нет конструкторов по-умолчанию, а boost::mpl::inherit требует наличия конструктора по-умолчанию, так что boost::mpl::inherit не использовал, а в стать вполне можно.
Спасибо за замечание.
Немножко колдунства и рукоделия
// тэг для вызова конструктора без параметров
enum skipctor_type { skipctor };

// boost::mpl::inherit своими руками
template<class... Bases> struct derived_;
template<> struct derived_<> {};
template<class Base, class... Bases> struct derived_<Base,Bases...>
	: Base, derived_<Bases...>
{
	// дефолт-конструктор предполагает дефолт-конструктор у всех баз, начиная с этой
	derived_()
		{}
	
	// скип-конструктор - эту базу по дефолту, остальные по списку
	template<class... Args>
	derived_(skipctor_type arg, Args&&... args)
		: derived_<Bases...>(args...)
		{}
	
	// все базы по списку
	template<class Arg, class... Args>
	derived_(Arg&& arg, Args&&... args)
		: Base(arg)
		, derived_<Bases...>(args...)
		{}
};



template<class... Bases> struct derived : derived_<Bases...>
{
	typedef derived allbases;
	typedef boost::mpl::vector<Bases...> baseclasses;
	
	derived() {}
	
	template<class... Args>
	derived(Args&&... args)
		: derived_<Bases...>(args...)
		{}
};

struct A { A(int,int,int) {} };
struct B { };
struct C { C(int) {} };

struct D : derived<A,B,C>
{
	D() : allbases(A(1,2,3),skipctor,4) {}
};

Создание иерархии — можно было, как это сделано в inherit_linearly, выразить через fold, но проще самому рекурсию написать, чем морочить голову.

С конструкторами — поддержать дефолтные и одноаргументные конструкторы (в частности, конструктор копирования или перемещения) легко, а вот чтобы транслировать кортежи в вариадики — т.е. чтобы можно было написать что-то в таком роде
struct D : derived<A,B,C>
{
//	D() : allbases(A(1,2,3),         skipctor,    4           ) {}
	D() : allbases(ctor_args(1,2,3), ctor_args(), ctor_args(4)) {}
};

это уже мозг немножко сломается. Теоретически, можно, но всё равно — для уже существующих замороженных базовых классов придётся выражать через конструкторы копирования-перемещения, а если их можно подправить, то проще добавить к их конструкторам ещё и конструкторы с аргументом tuple или initializer_list.
Впечатляет, спасибо!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации