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

## Pourquoi l'héritage multiple avec les classes de base de modèle provoque-t-il une ambiguïté dans la résolution des fonctions membres ?

Barbara Streisand
Libérer: 2024-10-25 04:58:02
original
529 Les gens l'ont consulté

## Why Does Multiple Inheritance with Template Base Classes Cause Ambiguity in Member Function Resolution?

Ambiguïté dans la levée de l'ambiguïté de l'héritage multiple

Lors du traitement de l'héritage multiple à l'aide de classes de base de modèles, un problème potentiel se pose concernant la résolution ambiguë des fonctions membres. Considérez le scénario suivant :

<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

Ici, la fonction foo() n'est appelable que lorsque le paramètre de modèle correspond à l'un des types du pack Types. Désormais, si une classe dérivée hérite de plusieurs classes de base avec des ensembles de types qui ne se chevauchent pas, le compilateur peut rencontrer une ambiguïté lors de la résolution de l'appel foo().

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{};</code>
Copier après la connexion

Dans ce cas, l'appel Derived(). foo() appellerait idéalement la fonction membre foo() de Base. Cependant, GCC et Clang signalent une ambiguïté.

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

L'erreur de compilation survient en raison des règles de fusion pour la recherche de fonctions membres. Selon le standard C, si la fonction membre n'est pas déclarée dans la classe dérivée elle-même, le processus de recherche recherche à son tour dans les classes de base. Cependant, si les ensembles de déclarations dans les classes de base diffèrent, la fusion devient ambiguë.

Dans le scénario donné, la classe dérivée Derived ne déclare pas explicitement foo(), le compilateur doit donc fusionner les ensembles de recherches du deux classes de base. Étant donné que les classes de base contiennent différents ensembles de déclarations pour foo(), la fusion entraîne une ambiguïté.

Solutions

Pour résoudre cette ambiguïté, une option consiste à utiliser des déclarations using dans la classe dérivée pour importer explicitement les fonctions membres souhaitées. Cependant, cela nécessite que l'utilisateur ajoute ces déclarations, ce qui peut être verbeux et peu pratique pour les grandes listes de types.

<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

Alternativement, on peut utiliser une classe d'assistance qui collecte et fusionne les fonctions membres de toutes les classes de base. , permettant à la classe dérivée d'y accéder directement.

<code class="cpp">template <typename... Bases>
struct BaseCollector : Bases...
{
  using Bases::foo...;
};

struct Derived : BaseCollector<Base<int, char>, Base<double, void>>
{};</code>
Copier après la connexion

Avec cette approche, l'utilisateur n'a pas besoin d'ajouter de déclarations supplémentaires pour résoudre l'ambiguïté. La classe BaseCollector fusionne efficacement les ensembles de déclarations de toutes les classes de base, rendant la fonction foo() disponible pour la classe dérivée sans ambiguïté.

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!