Maison > développement back-end > C++ > le corps du texte

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
Libérer: 2024-10-25 06:23:02
original
253 Les gens l'ont consulté

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";
    }
};
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!