Zugriff auf Typen von abhängigen Basisklassen
-
21-08-2019 - |
Frage
Weiß jemand, warum mit Erklärungen scheinen nicht für den Import von Typnamen aus abhängigen Basisklassen zu arbeiten? Sie arbeiten für Membervariablen und Funktionen, aber zumindest in GCC 4.3, scheinen sie für Typen ignoriert werden.
template <class T>
struct Base
{
typedef T value_type;
};
template <class T>
struct Derived : Base<T>
{
// Version 1: error on conforming compilers
value_type get();
// Version 2: OK, but unwieldy for repeated references
typename Base<T>::value_type get();
// Version 3: OK, but unwieldy for many types or deep inheritance
typedef typename Base<T>::value_type value_type;
value_type get();
// Version 4: why doesn't this work?
using typename Base<T>::value_type;
value_type get(); // GCC: `value_type' is not a type
};
Ich habe eine Basisklasse mit einem Satz von Allocator-Stil typedefs, die ich über mehrere Ebenen der Vererbung erben möchten. Die beste Lösung, die ich bisher gefunden habe ist Version 3 oben, aber ich bin neugierig, warum Version 4 nicht zu funktionieren scheint. GCC nimmt die using-Deklaration, aber scheint es zu ignorieren.
Ich habe den C ++ Standard C ++ Prog geprüft. Lang. 3. Aufl. [Stroustrup] und C ++ Templates [Vandevoorde, Josuttis], aber keiner scheint zu klären, ob Deklarationen verwendet, kann auf abhängige Basisklasse Typen angewendet werden.
Im Fall hilft es, ein anderes Beispiel zu sehen, hier ist die gleiche Frage gestellt werden, aber nicht wirklich beantwortet, auf der GCC-Mailingliste. Der Fragesteller hat zeigt an, dass er an anderer Stelle gesehen ‚mit Typnamen‘, aber das GCC scheint nicht zu unterstützen. Ich habe nicht einen anderen konformen Compiler zur Verfügung zu testen.
Lösung
Wie Richard Corden weist darauf hin, wurde diese Frage in der C ++ Standard-Core-Sprache Defect Report nach dem 2003-Standard ratifiziert wurde: Wie die Schlüsselwörter Typname / template interagieren mit der Verwendung von Deklarationen?
Vorgeschlagene Auflösung (April 2003 überarbeitet Oktober 2003):
Fügen Sie einen neuen Absatz auf den Grund 7.3.3 [namespace.udecl]:
Wenn eine using-Deklaration verwendet die Schlüsselwort typename und gibt ein Abhängiger Name (14.7.2 [temp.dep]), der Name durch die eingeführten Verwendung Deklaration wird als behandeltes typedef-name (7.1.3 [dcl.typedef]).
Dieser Text scheint nicht vom 15. Oktober 2003 in der Second Edition Standard erscheinen.
GCC noch nicht, diese Entschließung umzusetzen, wie in Bug 14258 erklärt :
------- Kommentar # 3 Von Giovanni Bajo 2004-02-27 00.47 [antworten] ------- Die Problem ist, dass unser USING_DECL nicht notieren Sie die „Typname“, das ist die Tatsache, dass es sich um eine Art, die ist durch sie importiert. Dies ist früher zur Arbeit Dank der impliziten Typnamen Erweiterung, glaube ich.
Bug 21484 , dass 'mit Typname' funktioniert auf Comeau zeigt und Intel Compiler. Da MSVC alle Namen behandelt, als abhängig, das Konstrukt ist nicht erforderlich (aber erlaubt) für diesen Compiler.
Fest in GCC 4.7 am 13. Dezember 2011
Andere Tipps
Sie haben keinen Zugriffsbezeichner (public / protected / privat) in der Vorlage für Base enthalten, bevor die typedef für Base :: value_type erklärt. Als Ergebnis ist es standardmäßig privat und nicht zugänglich in Klassen von Grunde abgeleitet.