Я хочу пройти Derived
класс в качестве параметра шаблона Base<T>
учебный класс.
Когда мой Derived
класс — это шаблон, и он очень длинный, у моего кода незначительные проблемы с удобством обслуживания и читаемостью, например,
template<class Derived>class Base{ //library : don't modify me
};
template<template<class>class T1,class T2,class T3>class Derived : //user class
public Base<Derived<T1,T2,T3>>{
};
У меня есть несколько случаев, когда у Derived много шаблонов, и мне приходится несколько раз набирать / копировать-вставлять его: —
template<template<class>class T1,class T2,class T3>class HyperDatabase : //user class
public IndexManager<HyperDatabase<T1,T2,T3>>,
public AwesomeHash<HyperDatabase<T1,T2,T3>,BitShifter>,
public Allocator<AlloDefault,HyperDatabase<T1,T2,T3>> { // etc...
};
Есть ли способ сделать его более кратким?
Я мечтаю о чем-то вроде: —
template<template<class>class T1,class T2,class T3>class Derived : //user class
public Base<Derived>{
};
ИЛИ ЖЕ
template<template<class>class T1,class T2,class T3>class Derived : //user class
public Base<MEEEEEEE>{
};
Использовать макрос #define MEEEEEEE Derived<T1,T2,T3>
,
Двойное наследство: слишком неловко
template<class T>class Base2: public Base<T>{};//user class
template<template<class>class T1,class T2,class T3>class Derived : //user class
public Base2<Derived<T1,T2,T3>>{
};
Вы можете написать variadic crtp combiner:
template <class T, template <class> ...Cs>
struct CrtpCombiner : Cs<T>... {};
Использование:
template<template<class>class T1,class T2,class T3>class
HyperDatabase : CrtpCombiner<HyperDataBase<T1, T2, T3>,
IndexManager, BitHash, DefaultAllocator>-
{ // etc...
};
Где BitHash и DefaultAllocator являются псевдонимами шаблона (с помощью объявлений), которые блокируют все аргументы шаблона, кроме производных.
Других решений пока нет …