Pourquoi utilisez-vous typedef lors de la déclaration d’un enum en C ++?

Je n’ai écrit aucun C ++ depuis des années et j’essaie maintenant d’y revenir. J’ai alors couru à travers cela et pensé à abandonner:

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

Qu’est-ce que c’est? Pourquoi le mot-clé typedef -il utilisé ici? Pourquoi le nom TokenType apparaît-il deux fois dans cette déclaration? En quoi la sémantique est-elle différente de ceci:

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

Related of "Pourquoi utilisez-vous typedef lors de la déclaration d’un enum en C ++?"

En C, déclarer votre énumération en premier lieu vous permet de l’utiliser comme ceci:

 TokenType my_type; 

Si vous utilisez le second style, vous serez obligé de déclarer votre variable comme ceci:

 enum TokenType my_type; 

Comme mentionné par d’autres, cela ne fait aucune différence en C ++. Je suppose que soit la personne qui a écrit ceci est un programmeur C au coeur, ou vous comstackz le code C en C ++. De toute façon, cela n’affectera pas le comportement de votre code.

C’est un inheritance C, en C, si vous le faites:

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

vous devrez l’utiliser pour faire quelque chose comme:

 enum TokenType foo; 

Mais si vous faites ceci:

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

Vous pourrez déclarer:

 TokenType foo; 

Mais en C ++, vous ne pouvez utiliser que l’ancienne définition et l’utiliser comme si elle se trouvait dans un C typedef.

Vous n’avez pas besoin de le faire. En C (pas en C ++), vous deviez utiliser enum Enumname pour faire référence à un élément de données du type énuméré. Pour le simplifier, vous avez été autorisé à le saisir dans un type de données à un seul nom.

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

les fonctions autorisées prenant un paramètre de l’énum à définir comme

 void f( MyEnum x ) 

au lieu de la plus longue

 void f( enum MyEnum x ) 

Notez que le nom du typename n’a pas besoin d’être égal au nom de l’énumération. La même chose se produit avec les structures.

En C ++, par contre, ce n’est pas obligatoire, car les énumérations, les classes et les structures peuvent être accédées directement en tant que types par leurs noms.

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

En C, c’est un bon style car vous pouvez changer le type en quelque chose en plus d’un enum.

 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 ++, vous pouvez définir l’énum pour qu’il soit compilé en C ++ ou C.

Holdover de C.

Certaines personnes disent que C n’a pas d’espaces de noms, mais ce n’est pas techniquement correct. Il en a trois:

  1. Tags ( enum et struct )
  2. Étiquettes
  3. Global (tout le rest)

typedef enum { } XYZ; déclare une énumération anonyme et l’importe dans l’espace de noms global sous le nom XYZ .

typedef enum ABC { } XYZ; déclare une énumération nommée ABC dans l’espace de noms de la balise, puis l’importe dans l’espace de noms global en tant que XYZ .

Idem tout cela pour le nom de domaine struct.

Certaines personnes ne veulent pas se soucier des espaces de noms séparés pour pouvoir tout saisir. D’autres n’ont jamais typescript, car ils veulent un espace de noms.

C’est un peu vieux, mais de toute façon, j’espère que vous apprécierez le lien que je suis sur le sharepoint taper, comme je l’ai apprécié au début de l’année.

Le voici Je devrais citer l’explication qui est toujours dans mon esprit quand je dois saisir certains types de méchants:

Dans les déclarations de variables, les noms introduits sont des instances des types correspondants. […] Cependant, lorsque le mot-clé typedef précède la déclaration, les noms introduits sont des alias des types correspondants

Comme beaucoup de personnes l’ont déjà dit, il n’est pas nécessaire d’utiliser des typedefs déclarant des énumérations en C ++ . Mais c’est l’explication de la syntaxe de typedef! J’espère que ça aide (Probablement pas OP, ça fait presque 10 ans, mais quiconque a du mal à comprendre ce genre de choses).

Dans certains guides de codest en C, la version typedef serait préférable pour la “clarté” et la “simplicité”. Je ne suis pas d’accord, car le typedef masque la nature réelle de l’object déclaré. En fait, je n’utilise pas les typedefs car lorsque vous déclarez une variable C, je veux être clair sur l’object réel de l’object. Ce choix me permet de me souvenir plus rapidement de ce que fait un ancien élément de code et aidera les autres utilisateurs à conserver le code ultérieurement.

La réponse réelle à la question “pourquoi” (qui est étonnamment ignorée par les réponses existantes en haut de cette ancienne question) est que cette déclaration enum est probablement située dans un fichier d’en-tête destiné à être compilable en code C et C ++ ( c’est-à-dire inclus dans les implémentations C et C ++). L’art d’écrire de tels fichiers d’en-tête repose sur la capacité de l’auteur à sélectionner les fonctionnalités linguistiques qui ont la signification compatible appropriée dans les deux langues.