Héritage multiple avec modèles variadiques: comment appeler une fonction pour chaque classe de base?

J’ai un programme de succession de diamants, où le dernier enfant devrait pouvoir hériter de nombreux parents différents.

A /|\ / | \ BC ... | | | * * DE 

Maintenant, imaginons que j’ai une class D : public B , une class E : public B, public C , etc. De D je veux appeler la même fonction de tous ses parents, ce qui est garanti, à cause du pasortingmoine. Je pensais que je pourrais envelopper ceci dans un modèle variadique.

Actuellement j’ai ceci:

 template  class A { public: A(T t) : mT(t) {} virtual ~A() {} virtual void doThings() = 0; protected: T mT; }; template <typename T, typename A = A> class B : public A { public: B(T t) : A(t) {} virtual ~B() {} virtual void doThings() { std::cout << "B" << std::endl; } }; template <typename T, typename A = A> class C : public A { public: C(T t) : A(t) {} virtual ~C() {} virtual void doThings() { std::cout << "C" << std::endl; } }; 

Maintenant, je pensais pouvoir faire quelque chose comme ça, ce qui ne fonctionne évidemment pas:

 template  class ChildGenerator : public Args... { public: ChildGenerator(T t) : Args(t)... {} // The unpacking of the variadic template does not work here. // Do I need to make it recursive somehow? How can I do that without having to instantiate new classes B and C? void doThings() override { Args...::doThings();} }; 

J’espère que je pourrai l’utiliser de la manière suivante:

 int main() { using B = B; using C = C; B c1(0.0); C c2(1.0); ChildGenerator c3(2.0); c1.doThings(); c2.doThings(); c3.doThings(); } 

Résultats attendus (l’ordre n’a pas d’importance):

 B C B // <-- order of these two does not matter C // <-- 

Est-ce que ce que j’essaie de réaliser est possible?

Une façon de parcourir les bases variadiques:

 template  class ChildGenerator : public Args... { public: ChildGenerator(T t) : Args(t)... {} void doThings() override { int dummy[] = {0, (Args::doThings(), void(), 0)...}; static_cast(dummy); // avoid warning for unused variable } }; 

ou en C ++ 17, avec l’expression de pliage:

  void doThings() override { (static_cast(Args::doThings()), ...); } 

Utilisez une expression de pli (C ++ 17):

 void doThings() override { ((Args::doThings()) , ...);} 

Démo en direct