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"; } };
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>
Der Aufruf von Derived().foo
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>
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>
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!