zu Stevela des hinzuzufügen answer, das Problem mit dem Original-Code ist, dass Sie auf ein Mitglied beziehen, aber die Verwendung von Erklärung ist nicht selbst Mitglied Erklärung:
7.3.3/6 hat:
Eine Verwendungsdeklaration für ein Klassenmitglied soll eine Member-Deklaration sein.
Um dies zu unterstreichen, wird das folgende Beispiel funktioniert:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
Schließlich wird, wie von Igor Semenov here wies darauf hin, auch wenn Sie die Enum-Definition in einem Namensraum zu bewegen, wodurch die Verwendung Erklärung erlaubt, Die using-Deklaration deklariert den Namen des enum-Typs nur in den Namespace (Die Standardreferenz von 2003 ist 7.3.3/2).
namespace Sample
{
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
using Sample::BLUE;
void foo()
{
int j = BLUE; // OK
int i = RED; // ERROR
}
Dependent Basistypen
für Teil- und explizite Spezialisierungen zu ermöglichen, wenn der Compiler eine Klassenvorlage analysiert es keine Lookups in den abhängigen Basisklassen durchführt. Als Ergebnis, wird die folgende Variante mit Probe als Template nicht kompiliert:
template <typename T>
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
template <typename T>
class Derived : public Sample<T>
{
public:
using Sample<T>::Colour; // What kind of entity is Colour?
Colour foo() // Not OK!
{
return this->RED;
}
};
Das Problem ist, dass Derived::Colour
als ein Objekt durch den Compiler behandelt wird (14.6/2):
Ein Name in einer Template-Deklaration oder Definition verwendet und das ist abhängig von einem Template-Parameter wird angenommen, dass keine Art zu nennen, es sei denn die entsprechenden Name-Lookup einen Typnamen findet oder der Namen qualifiziert nach dem Schlüsselwort typename.
Betrachtet man die beiden Bedingungen für die Namen ein Typ zu sein:
- Lookup für
Colour
keine Art finden, weil die abhängige Basis Sample<T>
nicht gesucht wird. template <typename T>
class Derived : public Sample<T>
{
public:
using typename Sample<T>::Colour; // Colour is treated as a typedef-name
Colour foo() // OK
{
return this->RED;
}
};
Hinweis: Die '98 Version des Standards nicht erlauben typename
verwendet werden
- Der Name von ist
typename
Das Beispiel muss daher die typename
Schlüsselwort nicht qualifiziert mit einer using-Deklaration und so war der obige Fix nicht möglich. Siehe Accessing types from dependent base classes und CWG11.
Gibt es einen anderen Weg, dies zu tun – yesraaj
Nicht wirklich relevant für Ihre Frage per se, aber ich würde Ihnen dringend empfehlen, nicht alle Großbuchstaben Bezeichner für Enums und Konstanten zu verwenden. Präprozessor-#defines sind in C/C++ in der Regel nur in Großbuchstaben, und sie werden andere Symbole mit demselben Namen bearbeiten. –
Die Verwendung des Scope-Auflösungsoperators :: on enums (wie in "sample :: Color :: RED") ist eine Compiler-spezifische Erweiterung, nicht Standard C++. – bk1e