Nombre d’éléments dans une énumération

En C, existe-t-il un bon moyen de suivre le nombre d’éléments dans une énumération? j’ai vu

enum blah { FIRST, SECOND, THIRD, LAST }; 

Mais cela ne fonctionne que si les éléments sont séquentiels et commencent à zéro.

Je ne crois pas qu’il y en ait. Mais que feriez-vous avec un tel nombre s’ils ne sont pas séquentiels et que vous n’en avez pas déjà la liste quelque part? Et si elles sont séquentielles mais commencent à un numéro différent, vous pouvez toujours faire:

 enum blah { FIRST = 128, SECOND, THIRD, END }; const int blah_count = END - FIRST; 

Si vous n’affectez pas vos enums, vous pouvez faire quelque chose comme ceci:

 enum MyType { Type1, Type2, Type3, NumberOfTypes } 

NumberOfTypes sera évalué à 3, ce qui correspond au nombre de types réels.

Vieille question, je sais. Ceci est pour les googlers avec la même question.

Vous pouvez utiliser X-Macros

Exemple:

 //The values are defined via a map which calls a given macro which is defined later #define ENUM_MAP(X) \ X(VALA, 0) \ X(VALB, 10) \ X(VALC, 20) //Using the map for the enum decl #define X(n, v) [n] = v, typedef enum val_list { ENUM_MAP(X) //results in [VALA] = 0, etc... } val_list; #undef X //For the count of values #define X(n, v) + 1 int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1 #undef X 

Ceci est également transparent pour un IDE, donc l’auto-complétion fonctionnera correctement (comme c’est tout fait dans le pré-processeur).

Malheureusement non. Il n’y a pas.

Je sais que la question est très ancienne, mais comme la réponse acceptée est fausse, je me sens obligé de poster la mienne. Je vais reprendre l’exemple de la réponse acceptée, légèrement modifié. (En supposant que les énumérations sont séquentielles.)

 // Incorrect code, do not use! enum blah { FIRST = 0, SECOND, // 1 THIRD, // 2 END // 3 }; const int blah_count = END - FIRST; // And this above would be 3 - 0 = 3, although there actually are 4 items. 

Tout développeur connaît la raison: count = last - first + 1 . Et cela fonctionne avec n’importe quelle combinaison de signes (les deux extrémités sont négatives, les deux positives ou uniquement négatives à la première extrémité). Tu peux essayer.

 // Now, the correct version. enum blah { FIRST = 0, SECOND, // 1 THIRD, // 2 END // 3 }; const int blah_count = END - FIRST + 1; // 4 

Edit: en relisant le texte, j’ai un doute. Est-ce que END signifie ne pas faire partie des articles proposés? Cela me semble bizarre, mais bon, je suppose que cela pourrait avoir un sens …

Eh bien, comme les enums ne peuvent pas changer au moment de l’exécution, la meilleure chose à faire est de:

 enum blah { FIRST = 7, SECOND = 15, THIRD = 9, LAST = 12 }; #define blahcount 4 /* counted manually, keep these in sync */ 

Mais je trouve difficile d’envisager une situation dans laquelle cette information serait utile. Qu’est-ce que vous essayez de faire exactement?

 int enaumVals[] = { FIRST, SECOND, THIRD, LAST }; #define NUM_ENUMS sizeof(enaumVals) / sizeof ( int ); 
 #include  // M_CONC and M_CONC_ come from https://stackoverflow.com/a/14804003/7067195 #define M_CONC(A, B) M_CONC_(A, B) #define M_CONC_(A, B) A##B #define enum_count_suffix _count #define count(tag) M_CONC(tag, enum_count_suffix) #define countable_enum(tag, ...) \ enum tag {__VA_ARGS__}; \ const size_t count(tag) = sizeof((int []) {__VA_ARGS__}) / sizeof(int) // The following declares an enum with tag `color` and 3 constants: `red`, // `green`, and `blue`. countable_enum(color, red, green, blue); int main(int argc, char **argv) { // The following prints 3, as expected. printf("number of elements in enum: %d\n", count(color)); } 

Essaye ça:

entrez la description de l'image ici

C’est moche et il pourrait y avoir des compilateurs qui ne l’aiment pas, mais ça marche habituellement et utile. Vous pouvez l’utiliser pour chaque type d’énumération.