9
votes

Valider l'entier est un élément de classe Enum (C ++ 11)

J'ai une classe d'enum xxx

Je veux vérifier si certains entiers peuvent être convertis en un FOO . Quel serait le moyen idéal de faire cela? Ceci est pour le chèque d'exécution (l'entier n'est pas encore connu au moment de la compilation)

Je peux évidemment faire cela la manière difficile (écrire une fonction bool checkenum (foo); avec Un commutateur de gros cul revient vrai pour tous les cas sauf le par défaut), mais j'espérais qu'un mécanisme plus élégant qui évitait tant d'écriture. Mpl ou boost.preprocessor serait une solution parfaitement acceptable, mais une personne que j'ai malheureusement connue très peu sur


4 commentaires

Dupliqué possible de Comment vérifier si la valeur Enum est valide?


@Johnzwinck, presque; Ceci est la classe C ++ 11 Enum, qui est supposée être Safe-ER


C ++ 11 ne vous apporte aucune nouvelle fonctionnalité pour ce que vous voulez faire. Donc, vous êtes coincé avec ce que l'autre affiche a eu. J'aimerais avoir de meilleures nouvelles, vraiment!


@Lurscher: C'est plus sûr. Mais ce n'est pas magie . Le seul moyen pour vous de mettre une valeur dans une variable ENUM CLASSE N'EST PAS l'un des énumérateurs est pour vous de Subvert le système de type en utilisant une distribution. C'est vraiment à propos de Type-Safe car il va entrer en C ++: Si vous jouez par les règles, cela fonctionne. Si vous commencez à jeter des entiers aléatoires à un énumérateur, vous avez délibérément abandonné vos garanties.


3 Réponses :


0
votes

Il n'y a pas de moyen "idéal" de le faire. Toutes les manières vont avoir à impliquer un travail manuel.

Vous devez créer une structure de données contenant toutes les valeurs acceptables. Ensuite, recherchez cette structure de données avec la valeur d'exécution dont vous avez besoin. A std :: set ou std :: Unorded_sed_sed_sed_sed serait adéquat à cet effet.

Votre principale difficulté sera de maintenir cette liste, car il faudra être mis à jour chaque fois que vous modifiez votre classe Enum .


0 commentaires

0
votes

OK, je suis un peu marre de cette question (certaines de mes énumes sont près de 100 articles) J'ai donc décidé de l'aborder avec la génération de code, qui pourrait ne pas être la tasse de thé de tout le monde, mais j'ai réalisé que ce n'est vraiment pas un tel problème si gros.

Je suis allé pour Python Cog , ce qui me permet d'intégrer les extraits Python à l'intérieur des commentaires dans mes fichiers .h et .cpps et génère automatiquement le code. Je l'utilise essentiellement comme un système de macro impératif vraiment intelligatif: p>

J'ai ajouté ce qui suit à test.h code> p>

]]]*/
 const unsigned int CatA_op_mask = (0 << 4); 
 const unsigned int CatSuper8_op_mask = (1 << 4); 



 enum class multiFooEnum { 
 A1 = CatA_op_mask | 0  , 
 A2 = CatA_op_mask | 1  , 
 A3_foo = CatA_op_mask | 2  , 

 Z1_bla = CatSuper8_op_mask | 0  , 
 Z10 = CatSuper8_op_mask | 1  , 
 Z11 = CatSuper8_op_mask | 2 

 };


uint32_t FromOpToIndex(multiFooEnum a) { 
 switch (a)
 {
case A1:
 return 0; 

case A2:
 return 1; 

case A3_foo:
 return 2; 

case Z1_bla:
 return 3; 

case Z10:
 return 4; 

case Z11:
 return 5; 

 } 
 } 


//[[[end]]]


1 commentaires

J'ai vu la solution de génération de code effectuée plusieurs fois. Quelques astuces supplémentaires que vous pouvez faire: convertir / depuis des chaînes, vers / depuis des valeurs entières (avec validation / affirmation lorsqu'il est invalide), et joignez-la dans une structure, génère automatiquement des constantes max / invalides (avec un nom cohérent pour tous vos énumérums ). C'est une chose de gonflement.



2
votes

Une solution à ce problème consiste à abandonner l'ENUMS et à le remplacer par des tableaux créés à l'aide de xmacros.


0 commentaires