Je dispose d'une hiérarchie de classes à une seule héritage définie comme suit :
struct A { using Parent = void; void fnct() { std::cout << "A\n"; } };
struct AA : A { using Parent = A; void fnct() { std::cout << "AA\n"; } };
struct AB : A { using Parent = A; void fnct() { std::cout << "AB\n"; } };
struct AAA : AA { using Parent = AA; void fnct() { std::cout << "AAA\n"; } };
struct AAB : AA { using Parent = AA; void fnct() { std::cout << "AAB\n"; } };
struct ABA : AB { using Parent = AB; void fnct() { std::cout << "ABA\n"; } };
struct ABB : AB { using Parent = AB; void fnct() { std::cout << "ABB\n"; } };
Chaque classe dans la hiérarchie définit un alias Parent
vers sa classe parent directe, et une fonction membre void fnct()
.
J'ai dû définir une fonction modèle call_fnct_upto_parent(C&)
qui, pour un objet donné de classe C
et une classe parent donnée P
de la hiérarchie de classes, appelle toutes les fonctions membres fnct()
du type d'objet C
jusqu'au type parent P
. J'ai implémenté cela en utilisant le SFINAE comme suit :
template
typename std::enable_if::value,void>::type call_fnct_upto_parent(C& c)
{
c.fnct();
static_assert(!std::is_same::value, "parent not found");
call_fnct_upto_parent(c);
}
template
typename std::enable_if::value,void>::type call_fnct_upto_parent(C& c)
{
c.fnct();
}
La fonction call_fnct_upto_parent(C&)
définie ci-dessus fonctionne comme prévu tant que P
est parent de C
. Par exemple, un appel à call_fnct_upto_parent(aaa)
, où aaa
est de type AAA
, entraîne des appels successifs à aaa.AAA::fnct()
, aaa.AA::fnct()
et aaa.A::fnct()
, résolus au moment de la compilation.
Maintenant, j'aimerais définir une fonction modèle call_fnct_upto_common_parent(Co&)
qui, pour un objet donné de classe Co
et une classe donnée Ch
de la hiérarchie de classes, appelle toutes les fonctions membres fnct()
du type d'objet Co
jusqu'au type P
du parent commun le plus proche des classes Ch
et Co
. Par exemple, un appel à call_fnct_upto_common_parent(aaa)
, conduirait à des appels successifs à aaa.AAA::fnct()
, aaa.AA::fnct()
et aaa.A::fnct()
, car la classe A
est le parent commun le plus proche des classes AB
et AAA
.
Une telle fonction peut-elle être implémentée et comment ? Une solution avec des appels résolus au moment de la compilation serait préférable, si c'est réalisable.
Merci pour votre aide.