1

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

  1. since it is possible to call a single doThings(), like in

    static_cast( ( tuple_element<0,Bases>::type::doThings()) );

thus an index_sequence would make it, although slightly less elegant.

  1. 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.

  • The answer depends on what you want to do with `Bases` exactly. What you show calls a member function on each base class. You can do other things using the other fold expressions, or template parameter pack expansion if you want to e.g. pass each base to a function as arguments. I'm not sure how having a type alias for the parameter pack would somehow help anything so please explain what you are actually trying to do. – rubenvb Jan 27 '21 at 08:06
  • Exactly, I'm asking to call member function on each base class, using `Bases` instead of `A`. – Michael Medvinsky Jan 27 '21 at 19:43
  • The `Bases` type alias isn't going to help you call a member function on each base class, as you already have the parameter pack which can be expanded with a fold expression to do what I understand you want to do. You'll need to clarify what it is exactly you want to be able to do (uncompilable pseudocode is fine, as long as we can understand from it what it is you really want to do). – rubenvb Jan 28 '21 at 09:13
  • @rubenvb, sorry for the delay, I edited the text. – Michael Medvinsky Jan 30 '21 at 18:50
  • There's not much left to write in an answer. Probably your solution #2 is the best you'll get. – aschepler Jan 30 '21 at 19:11
  • yes, I also think so, but figured it out after this question was originally posted. – Michael Medvinsky Jan 30 '21 at 23:27

0 Answers0