Moyen générique de cast int enum en C++
Est-il un générique façon de jeter int
à enum
dans C++
?
Si int
tombe dans la gamme d'un enum
il doit retourner un enum
valeur, autrement jeter un exception
. Est-il possible de l'écrire génériquement? Plus d'un enum type
doit être pris en charge.
Contexte: j'ai un externe enum type et aucun contrôle sur le code source. Je voudrais stocker cette valeur dans une base de données et de les récupérer.
enum e{x = 10000};
dans ce cas9999
tomber dans la gamme de laenum
?- Non,
9999
ne pas tomber. - Bonne question. Comme pour toute "pourquoi?" qui va apparaître, laissez-moi juste dire "la désérialisation" - semble une raison suffisante pour moi. Je serais également heureux d'entendre un de C++0x-compilant réponse pour
enum class
. - "Plage" est le bon mot ici, peut-être "domaine"?
- boost::numeric_cast<> jette un effet positif ou négatif exception de dépassement de la valeur en dehors des limites. Mais pas sûr que ce qui est vrai pour les types enum ainsi. Vous pouvez essayer.
Vous devez vous connecter pour publier un commentaire.
La chose la plus évidente consiste à annoter votre enum:
Vous avez besoin de la matrice pour être tenu à jour avec
e
, qui est une nuisance si vous n'êtes pas l'auteur dee
. Comme Sjoerd dit, il peut probablement être automatisé à l'aide de tout bon système de construction.Dans tous les cas, vous êtes contre 7.2/6:
Donc, si vous n'êtes pas l'auteur de
e
, vous peut ou peut ne pas avoir la garantie que les valeurs valides dee
fait apparaître dans sa définition.Laid.
Maintenant la vraie question. Pourquoi avez-vous besoin de cela? Le code est moche, pas facile à écrire (*?) et pas facile à maintenir, et pas facile à intégrer à votre code. Le code qu'il vous dit que c'est mal. Pourquoi se battre?
EDIT:
Sinon, étant donné que les énumérations sont des types intégraux en C++:
mais c'est encore plus laide que ci-dessus, beaucoup plus sujettes à des erreurs, et il ne lèvera pas que vous le désirez.
throw
(ou de faire quelque chose de spécial) pour les types invalides doivent avoir un commutateur, comme je l'ai posté.C++0x
?static_cast<MyEnum>
fonctionnera aussi bien, et doit être préférée à lareinterpret_cast<MyEnum>
enum my_enum_val
devrait probablement luMyEnum my_enum_val
, droit? Et lestatic_cast<MyEnum>(my_int_val)
va jeter simy_int_val
est hors de portée pour le type de données queMyEnum
en interne -- pas que c'est beaucoup d'aide pour votre moyenneint
...Si, comme vous le décrivez, les valeurs sont dans une base de données, pourquoi ne pas écrire un générateur de code qui lit ce tableau et crée un .h et .rpc fichier avec les enum et un
to_enum(int)
fonction?Avantages:
to_string(my_enum)
fonction.to_enum(int)
fonction sur cette base.make
, peuvent comparer les deux fichiers pour voir si le générateur doit être relancé.Pas - il n'y a pas d'introspection en C++, ni est-il construit dans le "domaine cochez la case" installation.
Que pensez-vous de celui-ci?
Vous pouvez ensuite utiliser le code que j'ai posté ici pour basculer sur les valeurs.
Apples::insert(4)
quelque part, donc cela n'a aucun avantage sur un interrupteur.Vous devriez voulez pas quelque chose comme ce que vous décrivez existe, j'en ai peur il ya des problèmes dans votre conception du code.
Aussi, vous supposez que les énumérations viennent dans une gamme, mais ce n'est pas toujours le cas:
Ce n'est pas dans une plage: même si c'était possible, vous êtes censé vérifier chaque nombre entier de 0 à 2^n pour voir si elles correspondent à une valeur de l'enum?
Si vous êtes prêt à la liste de vos valeurs enum comme paramètres de modèle, vous pouvez le faire en C++ 11 avec varadic modèles. Vous pouvez voir cela comme une bonne chose, vous permettant d'accepter des sous-ensembles de l'valide les valeurs de l'enum dans différents contextes; souvent utile lors de l'analyse des codes à partir de sources externes.
Peut-être pas tout à fait aussi générique que vous le souhaitez, mais le code de vérification lui-même est généralisé, il vous suffit de spécifier le jeu de valeurs. Cette approche gère des lacunes, des valeurs arbitraires, etc.
C++0x alternative à la "laid" version, permet plusieurs énumérations. Les utilisations de l'initialiseur des listes plutôt que des commutateurs, un peu plus propre de l'OMI. Malheureusement, cela ne fonctionne pas autour de la nécessité de coder en dur les valeurs enum.
Essayer quelque chose comme cela: