¿Por qué usas typedef cuando declaras una enumeración en C ++?

No he escrito ningún C ++ en años y ahora estoy tratando de volver a entrar en él. Luego me encontré con esto y pensé en rendirme:

typedef enum TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType; 

¿Que es esto? ¿Por qué se usa la palabra clave typedef aquí? ¿Por qué el nombre TokenType aparece dos veces en esta statement? ¿Cómo es la semántica diferente de esto?

 enum TokenType { blah1 = 0x00000000, blah2=0x01000000, blah3=0x02000000 }; 

En C, declarar tu enumeración de la primera manera te permite usarla así:

 TokenType my_type; 

Si usa el segundo estilo, se lo forzará a declarar su variable así:

 enum TokenType my_type; 

Como lo mencionaron otros, esto no hace una diferencia en C ++. Supongo que la persona que escribió esto es un progtwigdor de C en el fondo, o está comstackndo el código C como C ++. De cualquier forma, no afectará el comportamiento de tu código.

Es un patrimonio C, en C, si lo haces:

 enum TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 }; 

deberás usarlo haciendo algo como:

 enum TokenType foo; 

Pero si haces esto:

 typedef enum e_TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType; 

Podrás declarar:

 TokenType foo; 

Pero en C ++, puede usar solo la definición anterior y usarla como si estuviera en un typedef de C.

No es necesario que lo hagas En C (no en C ++) se le solicitó usar enumeración Enum para referirse a un elemento de datos del tipo enumerado. Para simplificarlo, se le permitió escribirlo en un solo tipo de datos de nombre.

 typedef enum MyEnum { //... } MyEnum; 

funciones permitidas tomando un parámetro de la enumeración que se definirá como

 void f( MyEnum x ) 

en lugar de la más larga

 void f( enum MyEnum x ) 

Tenga en cuenta que el nombre de typename no necesita ser igual al nombre de la enumeración. Lo mismo sucede con las estructuras.

En C ++, por otro lado, no es necesario, ya que las enums, las clases y las estructuras se pueden acceder directamente como tipos por sus nombres.

 // C++ enum MyEnum { // ... }; void f( MyEnum x ); // Correct C++, Error in C 

En C, es un buen estilo porque puede cambiar el tipo a algo además de una enumeración.

 typedef enum e_TokenType { blah1 = 0x00000000, blah2 = 0X01000000, blah3 = 0X02000000 } TokenType; foo(enum e_TokenType token); /* this can only be passed as an enum */ foo(TokenType token); /* TokenType can be defined to something else later without changing this declaration */ 

En C ++ puede definir la enumeración para que se compile como C ++ o C.

Holdover de C.

Algunas personas dicen que C no tiene espacios de nombres, pero eso no es técnicamente correcto. Tiene tres:

  1. Etiquetas ( enum y struct )
  2. Etiquetas
  3. Global (todo lo demás)

typedef enum { } XYZ; declara una enumeración anónima y la importa en el espacio de nombres global con el nombre XYZ .

typedef enum ABC { } XYZ; declara una enumeración llamada ABC en el espacio de nombre de la etiqueta, luego la importa en el espacio de nombre global como XYZ .

Lo mismo ocurre con el espacio de nombres struct.

Algunas personas no quieren molestarse con los espacios de nombres separados, así que escriben todo. Otros nunca escriben porque quieren el espacio de nombres.

Esto es algo antiguo, pero de todos modos, espero que aprecien el enlace que estoy a punto de escribir, ya que lo aprecié cuando me enteré a principios de este año.

Aquí está . Debo citar la explicación que siempre tengo en mente cuando tengo que entender algunos typedefs desagradables:

En las declaraciones de variables, los nombres introducidos son instancias de los tipos correspondientes. […] Sin embargo, cuando la palabra clave typedef precede a la statement, los nombres introducidos son alias de los tipos correspondientes

Como mucha gente dijo anteriormente, no hay necesidad de usar typedefs declarando enumeraciones en C ++ . ¡Pero esa es la explicación de la syntax del typedef! Espero que ayude (Probablemente no OP, ya que han pasado casi 10 años, pero cualquiera que esté luchando por comprender este tipo de cosas).

En algunas guías de estilo de código C, se dice que la versión typedef es preferible para “claridad” y “simplicidad”. No estoy de acuerdo, porque el typedef ofusca la verdadera naturaleza del objeto declarado. De hecho, no uso typedefs porque al declarar una variable C quiero dejar en claro qué es realmente el objeto. Esta elección me ayuda a recordar más rápido lo que realmente hace un viejo código y ayudaré a otros a mantener el código en el futuro.

La respuesta real a la pregunta “por qué” (que es sorprendentemente ignorada por las respuestas existentes encabeza esta vieja pregunta) es que esta statement enum probablemente se encuentra en un archivo de cabecera que se pretende comstackr como código C y C ++ ( es decir, incluido en los archivos de implementación C y C ++). El arte de escribir dichos archivos de encabezado depende de la capacidad del autor para seleccionar funciones de idioma que tengan el significado compatible adecuado en ambos idiomas.