Heim > Backend-Entwicklung > C++ > Hauptteil

Warum kommt es in C beim Aufruf einer Variadic-Template-Member-Funktion zu Mehrfachvererbungsmehrdeutigkeiten?

Susan Sarandon
Freigeben: 2024-10-25 01:50:30
Original
829 Leute haben es durchsucht

Why Does Multiple Inheritance Ambiguity Occur in C   When Calling a Variadic Template Member Function?

Begriffsklärung von Klassenmitgliedern mit Mehrfachvererbung

Betrachten Sie die folgende variadische Basisklassenvorlage:

<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"; }
};
Nach dem Login kopieren

The foo() Member kann nur mit einem Vorlagenparameter aufgerufen werden, der einem der Typen im Types-Paket entspricht. Definieren wir nun eine abgeleitete Klasse mit nicht überlappenden Basistypen:

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

Der Aufruf von Derived().foo() sollte intuitiv in Base aufgelöst werden. Basisklasse. Der Compiler beschwert sich jedoch über Mehrdeutigkeit.

Warum der Compiler die Mehrdeutigkeit nicht auflösen kann:

Die Zusammenführungsregeln für die Mitgliedersuche [class.member.lookup] geben an, wann Die abgeleitete Klasse verfügt über einen leeren Deklarationssatz (keine Mitglieder). Die Suchsätze aller Basisklassen müssen zusammengeführt werden. In unserem Fall haben die Basisklassen unterschiedliche Deklarationssätze, sodass die Zusammenführung fehlschlägt.

Lösungen:

Um diese Mehrdeutigkeit zu vermeiden, können wir using-Deklarationen zu den abgeleiteten Klassen hinzufügen Klasse:

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

Durch die Einführung von Überladungen von foo in der abgeleiteten Klasse umgehen wir effektiv die Zusammenführungsregeln.

Verwendung einer Collector-Klasse:

Alternativ können wir eine Vorlagenklasse verwenden, um die Using-Deklarationen aus allen Basisklassen zu aggregieren:

<code class="cpp">template <typename... Bases>
struct BaseCollector;

template <typename Base, typename... Bases>
struct BaseCollector<Base, Bases...> : Base, BaseCollector<Bases...> {
    using Base::foo;
    using BaseCollector<Bases...>::foo;
};

struct Derived : BaseCollector<Base2<int>, Base2<std::string>> {};</code>
Nach dem Login kopieren

Dieser Ansatz ist in C 17 effizienter zu kompilieren, da er eine Paketerweiterung von Using-Deklarationen ermöglicht.

Das obige ist der detaillierte Inhalt vonWarum kommt es in C beim Aufruf einer Variadic-Template-Member-Funktion zu Mehrfachvererbungsmehrdeutigkeiten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!