3 votes

Comment trouver le parent commun de deux classes dans une hiérarchie de classes

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.

3voto

TartanLlama Points 1461

Vous pourriez utiliser std::is_base_of avec une structure similaire à votre code existant :

template
typename std::enable_if::value,void>::type 
call_fnct_upto_common_parent(U& u)
{
    u.fnct();
    static_assert(!std::is_same::value, "parent not found");
    call_fnct_upto_common_parent(u);
}

template
typename std::enable_if::value,void>::type 
call_fnct_upto_common_parent(U& u)
{
    u.fnct();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X