Enum string en C++11
Je me rends compte de ce il a été demandé avant plus d'une fois mais je ne pouvais pas trouver une question explicitement la recherche d'une solution à ce problème avec C++11, donc, ici, nous allons à nouveau..
Nous pouvons facilement obtenir la chaîne de valeur de l'enum avec C++11?
I. e. est-il (aujourd'hui) tout intégré dans les fonctionnalités de C++11 qui nous permet d'obtenir une représentation de chaîne des types enum comme dans
typedef enum {Linux, Apple, Windows} OS_type;
OS_type myOS = Linux;
cout << myOS
ce serait imprimer Linux
sur la console?
- Probablement, rien n'a changé dans ce domaine.
- Depuis c++11 n'ai pas ajouter des réflexion, je doute qu'il existe de meilleures solutions maintenant.
- La question initiale que vous avez mentionné contient ÉGALEMENT une mise à jour, C++11 approche, si vous suffit de faire défiler passé les 2 ou 3 premières réponses.
- Stringification de noms de variables, ou les noms de type n'est pas directement possible. Vous avez à travailler avec des modèles (spécialisé pour chaque nom), les macros ou une combinaison de ceux-ci. Rien n'a vraiment changé en C++11 et autant que je sache, ne sera pas en C++14.
- C'est dommage 🙁
- Quelqu'un peut-il me donner quelques cas d'utilisation (pas de débogage de l'aide s'il vous plaît), parce que je ne manquez pas cette fonctionnalité?
- l'usage commun de client/serveur de code (chaque appel, et le type de données passe par le fil) ou tout simplement stocker des classes comme des fichiers Json.
- La sérialisation doivent être effectués pour d'autres types de données intégrés. Selon le protocole / format de fichier n'est pas chose facile, même pour les entiers. Les énumérations ne sont pas différents.
- voir open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3814.html
- Que faire si je veux
cout << myOS;
pour imprimer0
au lieu deLinux
? - Double Possible de Comment faire pour convertir un type enum variable une chaîne de caractères?
Vous devez vous connecter pour publier un commentaire.
La longue et inutile absence de générique enum chaîne de fonction en C++ (C) est douloureuse. C++11 n'ai pas l'adresse de ce, et autant que je sache, ni C++14.
Personnellement j'aimerais résoudre ce problème en utilisant la génération de code. Le préprocesseur C est une façon, vous pouvez voir quelques autres réponses liées dans les commentaires ici, pour que. Mais vraiment, je préfère écrire mes propres génération de code spécialement pour les énumérations. Il peut alors générer facilement
to_string (char*)
,from_string
,ostream operator<<
,istream operator<<
,is_valid
, et plus de méthodes que de besoin. Cette approche peut être très flexible et puissant, mais il applique la cohérence absolue dans de nombreuses énumérations dans un projet, et il n'entraîne pas de coût d'exécution.Faire à l'aide de Python excellent "mako" package ou en Lua si vous êtes dans le léger, ou du RPC si vous êtes contre les dépendances, ou CMake propres installations pour la génération de code. Beaucoup de moyens, mais tout revient à la même chose: vous avez besoin de générer le code vous-même--C++ de ne pas le faire pour vous (malheureusement).
J'aime un hack en utilisant le préprocesseur C, qui j'ai vu ici:
http://blogs.msdn.com/b/vcblog/archive/2008/04/30/enums-macros-unicode-and-token-pasting.aspx .
Il utilise le jeton-coller de l'opérateur # .
Franchement, c'est moche et. mais, en fin de saisie de votre enums exactement une FOIS dans un fichier inclus, ce qui est plus facile à gérer.
BTW, sur MSDN lien de blog (voir ci-dessus) d'un utilisateur fait un commentaire avec un truc qui rend le tout beaucoup plus joli, et évite #comprend:
(Je viens de remarquer que 0x17de réponse utilise également le jeton-coller de l'opérateur)
À mon avis, le plus maintenable approche consiste à écrire une fonction d'aide:
C'est une bonne idée pas à mettre en œuvre le "défaut" de cas, car cela permet de s'assurer que vous obtenez un avertissement du compilateur si vous oubliez de mettre en œuvre un cas (avec le droit de compilateur et les paramètres du compilateur).
Voici un exemple simple d'utilisation des espaces de noms et les structures.
Une classe est créée pour chaque enum élément. Dans cet exemple j'ai choisi
int
que le type de l'id.De sortie:
== Mise à jour ==
À l'aide de:
et en utilisant une seule fois avant la première utilisation de la ENUMITEM les id ne serait plus nécessaire.
La variable
enumStart
n'est accessible que par le biais de l'espace de noms est donc encore plusieurs énumérations peuvent être utilisés.Vous pouvez utiliser une macro pour résoudre ce problème:
Que la variable statique ne peut être initialisé une fois, de sorte que le Enum_##nom##_str_vec utilisera le Enum_##nom##_init() pour initialiser au premier.
L'exemple de code ci-dessous:
Ensuite, vous pouvez utiliser la phrase ci-dessous pour imprimer une valeur d'enum:
Et l'utilisation phrase ci-dessous pour imprimer toutes les enum comme une chaîne de caractères:
#define
aurait l'air beaucoup mieux avec une bonne indentation des blocs de code.Comme mentionné, il n'existe pas de méthode standard pour ce faire. Mais avec un peu de préprocesseur de la magie (similaire à AlejoHausner deuxième contribution) et certains modèles de la magie, il peut être assez élégant.
Inclure ce code une fois:
Puis définissez chaque enum comme suit:
Vous n'avez qu'à énumérer les valeurs enum une fois et le code pour définir le il est assez compact et intuitif.
Valeurs devront nécessairement être numérotées dans la méthode par défaut (c'est à dire, 0,1,2,...). Le code de
fromString()
suppose que les valeurs de l'enum sont en majuscules ou en minuscules (pour la conversion de chaînes de caractères) que la valeur par défaut est la première, mais vous pouvez bien sûr modifier la façon dont ces choses sont traitées.Ici est de savoir comment vous obtenez la valeur de chaîne:
Ici est de savoir comment vous définissez l'enum à partir d'une chaîne de valeur: