usando declaración con enum?
-
22-07-2019 - |
Pregunta
el uso de la declaración no parece funcionar con el tipo de enumeración
class Sample{
public:
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
no funciona !! ¿necesitamos agregar usando la declaración para cada enumerador de tipo enum? como abajo
using sample::Colour::RED;
Solución
Una clase no define un espacio de nombres, por lo tanto " usando " no es aplicable aquí.
Además, debe hacer pública la enumeración.
Si está intentando usar la enumeración dentro de la misma clase, aquí hay un ejemplo:
class Sample {
public:
enum Colour { RED, BLUE, GREEN };
void foo();
}
void Sample::foo() {
Colour foo = RED;
}
Y para acceder desde fuera de la clase:
void bar() {
Sample::Colour colour = Sample::RED;
}
Otros consejos
Para agregar a la respuesta de Stevela, el problema con el código original es que usted referirse a un miembro, pero la declaración de uso no es en sí misma una declaración de miembro:
7.3.3 / 6 tiene:
Una declaración de uso para un miembro de la clase será una declaración de miembro.
Para resaltar esto, el siguiente ejemplo funciona:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
Finalmente, como señaló Igor Semenov aquí , incluso si mueve el definición de enumeración en un espacio de nombres, lo que permite la declaración de uso, la declaración de uso solo declarará el nombre del tipo de enumeración en el espacio de nombres (la referencia estándar de 2003 es 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
}
Tipos de base dependientes
Para permitir especializaciones parciales y explícitas, cuando el compilador analiza una plantilla de clase no realiza ninguna búsqueda en clases base dependientes. Como resultado, la siguiente variación con Muestra como plantilla no se compila:
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;
}
};
El problema es que Derived::Colour
es tratado como un objeto por el compilador (14.6 / 2):
Se supone que un nombre usado en una declaración o definición de plantilla y que depende de un parámetro de plantilla no nombra un tipo a menos que la búsqueda de nombre aplicable encuentre un nombre de tipo o el nombre sea calificado por la palabra clave typename.
Observando las dos condiciones para que el nombre sea un tipo:
- La búsqueda de
Colour
no encuentra un tipo porque la base dependienteSample<T>
no se busca. - El nombre no está calificado por
typename
Por lo tanto, el ejemplo necesita la palabra clave <=>:
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;
}
};
Nota: la versión '98 del estándar no permitía que <=> se usara con una declaración de uso y, por lo tanto, la solución anterior no era posible. Consulte Acceso a tipos desde clases base dependientes y CWG11 .
Estándar C ++, 7.3.3.1:
El nombre del miembro especificado en un utilizando-declaración se declara en el región declarativa en la que el aparece la declaración de uso. [ Nota: solo el nombre especificado es así declarado; especificando una enumeración nombre en una declaración de uso no declarar sus enumeradores en el utilizando-declaración & # 8217; s declarativo región. & # 8212; nota final]