Maison  >  Article  >  développement back-end  >  Comment résoudre l'ambiguïté dans l'héritage multiple avec des types qui se chevauchent lors de l'appel de méthodes polymorphes ?

Comment résoudre l'ambiguïté dans l'héritage multiple avec des types qui se chevauchent lors de l'appel de méthodes polymorphes ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-25 06:23:02254parcourir

How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?

Désambiguïsation dans l'héritage multiple avec des types qui se chevauchent

L'héritage multiple peut conduire à des appels ambigus de membres de classe lorsque différentes classes de base ont des ensembles qui ne se chevauchent pas de types applicables pour les méthodes polymorphes. Considérons le scénario dans lequel un modèle de classe de base variadique, Base, définit une méthode, foo(), qui ne peut être invoquée qu'avec les paramètres de modèle contenus dans son pack de paramètres de type.

Dans notre exemple :

<code class="cpp">template <typename ... Types>
class Base {
public:
    template <typename T>
    typename std::enable_if<Contains<T, Types ...>::value>::type
    foo() {
        std::cout << "Base::foo()\n";
    }
};

Nous pouvons dériver une classe, Derived, qui hérite deux fois de Base avec des jeux de types qui ne se chevauchent pas :

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{};</code>

Lors de l'appel de Derived().foo(), le compilateur ne peut pas résoudre à partir de quelle classe de base invoquer foo(), conduisant à une erreur d'appel ambiguë.

Pourquoi le compilateur ne peut pas résoudre l'ambiguïté

Les règles de fusion pour la classe -member lookup indique que si l'ensemble de déclarations de la classe dérivée (dans ce cas, Derived) est vide, l'ensemble de recherche pour un membre (dans ce cas, foo) est fusionné à partir de toutes les classes de base directes. Cependant, comme nos classes de base ont des ensembles de déclarations différents pour foo, la fusion est ambiguë.

Solutions de contournement

Pour résoudre l'ambiguïté, nous pouvons créer l'ensemble de déclarations Derived non vide en ajoutant des déclarations using pour les méthodes foo dans les bases :

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{
    using Base<int, char>::foo;
    using Base<double, void>::foo;
};</code>

L'utilisation de déclarations amène les membres des classes de base dans la classe dérivée, fournissant ainsi à Derived deux surcharges de foo. Le compilateur peut alors appeler sans ambiguïté la surcharge appropriée.

Solutions alternatives

  • Classe de collecteur de base : Ce modèle de classe peut collecter à l'aide de déclarations pour plusieurs bases, réduisant ainsi le besoin de déclarations explicites.
  • Extension du pack en C 17 : L'extension du pack peut être utilisée pour simplifier le modèle BaseCollector en une seule ligne, le rendant plus concis et efficace à compiler.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn