using-Deklaration mit ENUM?
-
22-07-2019 - |
Frage
Erklärung mit scheint nicht mit Aufzählungstyp arbeiten
class Sample{
public:
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
funktioniert nicht !! brauchen wir mit Erklärung für jede Aufzählung von Aufzählungstyp hinzufügen? wie unter
using sample::Colour::RED;
Lösung
Eine Klasse wird nicht definiert, einen Namespace, also „mit“ hier nicht anwendbar ist.
Außerdem müssen Sie die Enum öffentlich machen.
Wenn Sie versuchen, die Enum innerhalb der gleichen Klasse zu verwenden, hier ein Beispiel:
class Sample {
public:
enum Colour { RED, BLUE, GREEN };
void foo();
}
void Sample::foo() {
Colour foo = RED;
}
Und es zuzugreifen, ohne die Klasse:
void bar() {
Sample::Colour colour = Sample::RED;
}
Andere Tipps
zu Stevela Antwort hinzuzufügen, das Problem mit dem Original-Code ist, dass Sie beziehen sich auf ein Mitglied, aber die Verwendung von Erklärung ist nicht selbst Mitglied Erklärung:
7.3.3 / 6 hat:
Eine using-Deklaration für eine Klasse Mitglied ist Mitglied 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, wie durch Igor Semenov hier wies darauf hin, auch wenn Sie sich bewegen die enum-Definition in einen Namensraum, wodurch die Verwendung von Erklärung, die unter Verwendung Erklärung nur den Namen des Typs in den Namensraum enum deklariert (die 2003-Standard Referenz 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
Damit für Teil- und explizite Spezialisierungen, wenn der Compiler eine Klassenvorlage analysiert es keine Lookups in den abhängigen Basisklassen durchführt. Als Ergebnis ist die folgende Variante mit der Probe als Vorlage nicht kompiliert werden:
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 (14,6 / 2):
Ein Name in einer Template-Deklaration oder Definition verwendet und das ist abhängig von einem Template-Parameter angenommen wird, nicht eine Art zu nennen, es sei denn der entsprechende Name-Lookup einen Typnamen oder den Namen findet durch das Schlüsselwort Type-Name qualifiziert.
für den Namen an den beiden Bedingungen der Suche ein Typ zu sein:
- Lookup für
Colour
findet keine Art, da die abhängige BasisSample<T>
nicht gesucht wird. - Der Name qualifiziert ist nicht von
typename
Das Beispiel muss daher das typename
Stichwort:
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 Standard-typename
verwendete mit einer using-Deklaration wird nicht zulassen und so die oben fix war nicht möglich. Siehe Typen von abhängigen Basisklassen Zugriff auf und CWG11 .
C ++ Standard 7.3.3.1:
Der Elementname in einer bestimmten using-Deklaration ist erklärtes deklarative Bereich, in dem der using-Deklaration erscheint. [ Hinweis: nur der angegebene Name ist so erklärt; Spezifizieren eines Aufzählungs Name in einer using-Deklaration nicht der Fall ist erklären ihre Aufzählungen in der using-Deklaration des deklarativen Region. -Ende note]