Consider the situation from here, which is mainly
template <typename T, typename ...Args>
class ChildGenerator : public Args...
{
public:
ChildGenerator(T t) : Args(t)... {}
void doThings() override { (static_cast<void>(Args::doThings()), ...);}
};
with a little difference is that the inheritance now looks more like A<Args>...
, i.e.
template<typename> class A{some code};
template <typename T, typename ...Args>
class ChildGenerator : public A<Args>...
{
public:
ChildGenerator(T t) : A<Args>(t)... {}
void doThings() override { (static_cast<void>(A<Args>::doThings()), ...);}
};
Everything looks good and elegant so far and even works, but the actual class A
of interest has a longer list of templates, e.g.
template <typename T1,typename T2,...,typename Tn, typename ...Args>
class ChildGenerator : public A<T1,T2,...,Tn,Args>...
This would make the code awkward, e.g.
void doThings() override { (static_cast<void>(A<T1,T2,...,Tn,Args>::doThings()), ...);}
especially if there are more than single doThings
function.
One way to typedef
the multiple bases is using tuple:
typedef std::tuple<A<T1,T2,...,Tn,Args>...> Bases;
however
void doThings() override { (static_cast<void>(A<Bases>::doThings()), ...);}
won't compile. The question is there way to make this working.
Alternative solutions I've found so far
since it is possible to call a single
doThings()
, like instatic_cast( ( tuple_element<0,Bases>::type::doThings()) );
thus an index_sequence
would make it, although slightly less elegant.
- a more elegant option would be
template < typename Arg > using Bases = A<T1,T2,...,Tn,Arg>;
then
(static_cast<void>(Bases<Args>::doThings()), ...);
is elegant enough, and the best option so far.