Supongamos que tenemos enum
lo siguiente:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Quiero crear una instancia de esto enum
e inicializarlo con un valor adecuado, así que hago:
Days day = Days.Saturday;
Ahora quiero verificar mi variable o instancia con un enum
valor existente , así que hago:
if (day == Days.Saturday)
{
std::cout << "Ok its Saturday";
}
Lo que me da un error de compilación:
error: expresión primaria esperada antes de '.' simbólico
Para que quede claro, ¿cuál es la diferencia entre decir:
if (day == Days.Saturday) // Causes compilation error
y
if (day == Saturday)
?
¿A qué se refieren realmente estos dos, en que uno está bien y uno causa un error de compilación?
Respuestas:
Este código está mal:
Porque
Days
no es un alcance, ni un objeto. Es un tipo. Y los Tipos en sí mismos no tienen miembros. Lo que escribiste es el equivalente astd::string.clear
.std::string
es un tipo, por lo que no puede usarlo.
. Usas.
en una instancia de una clase.Desafortunadamente, las enumeraciones son mágicas, por lo que la analogía se detiene allí. Porque con una clase, puede hacer
std::string::clear
para obtener un puntero a la función miembro, pero en C ++ 03,Days::Sunday
no es válido. (Lo cual es triste) Esto se debe a que C ++ es (algo) retrocompatible con C, y C no tenía espacios de nombres, por lo que las enumeraciones tenían que estar en el espacio de nombres global. Entonces la sintaxis es simplemente:Afortunadamente, Mike Seymour observa que esto se ha abordado en C ++ 11. Cambiar
enum
aenum class
y que llega a su propio ámbito de aplicación; asíDays::Sunday
que no solo es válido, sino que es la única forma de accederSunday
. ¡Días felices!fuente
enum
aenum class
y que llega a su propio ámbito de aplicación; asíDays::Sunday
que no solo es válido, sino que es la única forma de accederSunday
. ¡Días felices!'.' token
ydot operator
, aparte de que es un token y no un operador, y muestra el símbolo exacto, en lugar de un nombre.enum
, no puede usar ningún alcance o el alcance global (::Saturday
). Si tiene unenum class
(que es una cosa muy diferente), entonces tiene que usarDays::Saturday
.Esto será suficiente para declarar su variable enum y compararla:
fuente
Days
no es un alcance, ni un objeto. Es un tipo. Y los Tipos en sí mismos no tienen miembros.std::string.clear
Tampoco se compila por el mismo motivo.enum class
, nuevos en 2011) tienen su propio ámbito de aplicación, y se puede acceder mediante el operador alcanceDays::Saturday
. El operador de acceso de miembros (.
) solo se usa para acceder a los miembros de la clase.Gran parte de esto debería darte errores de compilación.
Ahora,
Saturday
,Sunday
, etc. puede ser utilizado como constantes desnudos de nivel superior, yDays
se puede utilizar como un tipo:Y de manera similar más tarde, para probar:
Estos
enum
valores son como constantes desnudas, sin ámbito, con un poco de ayuda adicional del compilador: (a menos que esté usando clases de enumeración de C ++ 11 ) no están encapsulados como miembros de objetos o estructuras, por ejemplo, y no puedes referirte a ellos como miembros deDays
.Tendrá lo que está buscando con C ++ 11 , que presenta un
enum class
:Tenga en cuenta que este C ++ es un poco diferente de C en un par de formas, una es que C requiere el uso de la
enum
palabra clave al declarar una variable:fuente
Puede usar un truco para usar los ámbitos como desee, simplemente declare enum de la siguiente manera:
fuente
En lugar de usar un montón de declaraciones if, las enumeraciones se prestan bien para cambiar las declaraciones
Utilizo algunas combinaciones de enum / switch en el generador de niveles que estoy construyendo para mi juego.
EDITAR: Otra cosa, veo que quieres una sintaxis similar a;
Puedes hacer esto en C ++:
Aquí hay un ejemplo muy simple:
EnumAppState.h
Somefile.cpp
fuente
Si todavía usa C ++ 03 y desea usar enumeraciones, debería usar enumeraciones dentro de un espacio de nombres. P.ej:
Puede usar la enumeración fuera del espacio de nombres como,
fuente
Está buscando enumeraciones fuertemente tipadas , una característica disponible en el estándar C ++ 11 . Convierte las enumeraciones en clases con valores de alcance.
Usando su propio ejemplo de código, es:
El uso
::
como accesores a las enumeraciones fallará si se dirige a un estándar C ++ anterior a C ++ 11. Pero algunos compiladores antiguos no lo admiten, y algunos IDE simplemente anulan esta opción y configuran un viejo estándar de C ++.Si está utilizando GCC, habilite C + 11 con -std = c ++ 11 o -std = gnu11 .
¡Sea feliz!
fuente
enum class Days { ...
.Esto no debería funcionar en C ++:
Days no es un ámbito u objeto que contenga miembros a los que pueda acceder con el operador de puntos. Esta sintaxis es solo un C # y no es legal en C ++.
Microsoft ha mantenido durante mucho tiempo una extensión C ++ que le permite acceder a los identificadores utilizando el operador de alcance:
Pero esto no es estándar antes de C ++ 11. En C ++ 03, los identificadores declarados en una enumeración solo existen en el mismo ámbito que el tipo de enumeración en sí.
C ++ 11 hace legal calificar los identificadores enum con el nombre enum, y también introduce clases enum, que crean un nuevo alcance para los identificadores en lugar de colocarlos en el alcance circundante.
fuente
Lamentablemente, los elementos de la enumeración son 'globales'. Accede a ellos haciendo
day = Saturday
. Eso significa que no puede tenerenum A { a, b } ;
yenum B { b, a } ;
porque están en conflicto.fuente
enum class
en C ++ 11, eso es. Antes de eso, tienes que hacer clases falsas.Si bien C ++ (excluyendo C ++ 11) tiene enumeraciones, los valores en ellas se "filtraron" en el espacio de nombres global.
Si no desea que se filtren (y NO NECESITA usar el tipo de enumeración), considere lo siguiente:
fuente
Las enumeraciones en C ++ son como enteros enmascarados por los nombres que les da, cuando declara sus valores de enumeración (esto no es una definición, solo una pista de cómo funciona).
Pero hay dos errores en su código:
enum
todo en minúsculasDays.
antes del sábado.if (day == YourClass::Saturday){}
fuente
Creo que su problema raíz es el uso de en
.
lugar de::
, que utilizará el espacio de nombres.Tratar:
fuente
Days::
alcance como en su ejemplo, debe definir la enumeraciónenum class Days
y usar C ++ 03 + extensión de Microsoft o C ++ 11.-std=c++98
o-std=c++03
. Sonido metálico es bastante claro:warning: use of enumeration in a nested name specifier is a C++11 extension
.Si queremos la seguridad estricta del tipo y la enumeración de ámbito, el uso
enum class
es bueno en C ++ 11.Si tuviéramos que trabajar en C ++ 98, podemos usar los consejos dados por
InitializeSahib
,San
para habilitar la enumeración de ámbito.Si también queremos la seguridad estricta del tipo, el siguiente código puede implementar algo así
enum
.El código se modifica a partir del ejemplo de la clase Mes en el libro Efectivo C ++ 3er: Artículo 18
fuente
En primer lugar, escriba 'E' en enumeración, 'e' como minúscula.
Segundo, suelte el nombre de tipo 'Días' en 'Días.Sábado'.
Tercero ... cómprate un buen libro de C ++.
fuente