Комментарии 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> {.....};
+1
В проекте у базовых структур нет конструкторов по-умолчанию, а boost::mpl::inherit требует наличия конструктора по-умолчанию, так что boost::mpl::inherit не использовал, а в стать вполне можно.
Спасибо за замечание.
Спасибо за замечание.
0
Немножко колдунства и рукоделия
Создание иерархии — можно было, как это сделано в inherit_linearly, выразить через fold, но проще самому рекурсию написать, чем морочить голову.
С конструкторами — поддержать дефолтные и одноаргументные конструкторы (в частности, конструктор копирования или перемещения) легко, а вот чтобы транслировать кортежи в вариадики — т.е. чтобы можно было написать что-то в таком роде
это уже мозг немножко сломается. Теоретически, можно, но всё равно — для уже существующих замороженных базовых классов придётся выражать через конструкторы копирования-перемещения, а если их можно подправить, то проще добавить к их конструкторам ещё и конструкторы с аргументом tuple или initializer_list.
// тэг для вызова конструктора без параметров
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.
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Обработка структуры по списку базовых типов