Heim  >  Artikel  >  Backend-Entwicklung  >  ## Warum führt die Mehrfachvererbung mit Vorlagenbasisklassen zu Mehrdeutigkeiten bei der Auflösung von Mitgliedsfunktionen?

## Warum führt die Mehrfachvererbung mit Vorlagenbasisklassen zu Mehrdeutigkeiten bei der Auflösung von Mitgliedsfunktionen?

Barbara Streisand
Barbara StreisandOriginal
2024-10-25 04:58:02530Durchsuche

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

Mehrdeutigkeit bei der Disambiguierung von Mehrfachvererbung

Beim Umgang mit Mehrfachvererbung mithilfe von Vorlagenbasisklassen entsteht ein potenzielles Problem hinsichtlich der Auflösung mehrdeutiger Mitgliedsfunktionen. Stellen Sie sich das folgende Szenario vor:

<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";
  }
};

Hier ist die Funktion foo() nur aufrufbar, wenn der Vorlagenparameter mit einem der Typen im Types-Paket übereinstimmt. Wenn nun eine abgeleitete Klasse von mehreren Basisklassen mit nicht überlappenden Typsätzen erbt, kann der Compiler beim Auflösen des foo()-Aufrufs auf Mehrdeutigkeiten stoßen.

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

In diesem Fall der Aufruf Derived(). foo() würde idealerweise die foo()-Memberfunktion von Base aufrufen. Allerdings melden sowohl GCC als auch Clang eine Mehrdeutigkeit.

Warum der Compiler die Mehrdeutigkeit nicht auflösen kann

Der Kompilierungsfehler entsteht aufgrund der Zusammenführungsregeln für die Suche nach Mitgliedsfunktionen. Gemäß dem C-Standard durchsucht der Suchprozess nacheinander die Basisklassen, wenn die Memberfunktion nicht in der abgeleiteten Klasse selbst deklariert ist. Wenn sich jedoch die Deklarationssätze in den Basisklassen unterscheiden, wird die Zusammenführung mehrdeutig.

Im gegebenen Szenario deklariert die abgeleitete Klasse Derived foo() nicht explizit, sodass der Compiler die Nachschlagesätze aus dem zusammenführen muss zwei Basisklassen. Da die Basisklassen unterschiedliche Deklarationssätze für foo() enthalten, führt die Zusammenführung zu Mehrdeutigkeiten.

Lösungen

Um diese Mehrdeutigkeit aufzulösen, besteht eine Möglichkeit darin, Deklarationen zu verwenden in der abgeleiteten Klasse, um die gewünschten Mitgliedsfunktionen explizit zu importieren. Dies erfordert jedoch, dass der Benutzer diese Deklarationen hinzufügt, was bei großen Typlisten ausführlich und unpraktisch sein kann.

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

Alternativ kann man eine Hilfsklasse verwenden, die die Mitgliedsfunktionen aller Basisklassen sammelt und zusammenführt , sodass die abgeleitete Klasse direkt darauf zugreifen kann.

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

struct Derived : BaseCollector<Base<int, char>, Base<double, void>>
{};</code>

Bei diesem Ansatz muss der Benutzer keine zusätzlichen Deklarationen hinzufügen, um die Mehrdeutigkeit aufzulösen. Die BaseCollector-Klasse führt effektiv die Deklarationssätze aller Basisklassen zusammen und macht die foo()-Funktion ohne Mehrdeutigkeit für die abgeleitete Klasse verfügbar.

Das obige ist der detaillierte Inhalt von## Warum führt die Mehrfachvererbung mit Vorlagenbasisklassen zu Mehrdeutigkeiten bei der Auflösung von Mitgliedsfunktionen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn