Existe-t-il un moyen simple en C++ de convertir une chaîne en un enum (similaire à Enum.Parse
en C #)? Une instruction switch serait très long, alors je me demandais s'il existait un moyen plus simple de le faire?
MODIFIER:
Merci pour toutes vos réponses. J'ai réalisé qu'il y avait un moyen beaucoup plus simple de le faire pour mon cas particulier. Les cordes contenaient toujours le caractère 'S' suivi d'un certain nombre, donc je viens de le faire
int i = atoi(myStr.c_str() + 1);
et ensuite fait un interrupteur i.
Un std::map<std::string, MyEnum>
(ou unordered_map
) pourrait le faire facilement. Remplir la carte serait tout aussi fastidieux que la déclaration switch.
Utilisez std::map<std::string, Enum>
et utilisez boost::map_list_of
pour facilement l’initialiser.
Exemple,
enum X
{
A,
B,
C
};
std::map<std::string, X> xmap = boost::map_list_of("A", A)("B", B)("C",C);
vu cet exemple quelque part
#include <map>
#include <string>
enum responseHeaders
{
CONTENT_ENCODING,
CONTENT_LENGTH,
TRANSFER_ENCODING,
};
// String switch paridgam
struct responseHeaderMap : public std::map<std::string, responseHeaders>
{
responseHeaderMap()
{
this->operator[]("content-encoding") = CONTENT_ENCODING;
this->operator[]("content-length") = CONTENT_LENGTH;
this->operator[]("transfer-encoding") = TRANSFER_ENCODING;
};
~responseHeaderMap(){}
};
J'utilise ces "astuces"> http://codeproject.com/Articles/42035/Enum-to-String-and-Vice-Versa-in-C
Après
enum FORM {
F_NONE = 0,
F_BOX,
F_CUBE,
F_SPHERE,
};
insérer
Begin_Enum_String( FORM )
{
Enum_String( F_NONE );
Enum_String( F_BOX );
Enum_String( F_CUBE );
Enum_String( F_SPHERE );
}
End_Enum_String;
Fonctionne bien si les valeurs enum ne sont pas dupliquées.
Exemple en code
enum FORM f = ...
const std::string& str = EnumString< FORM >::From( f );
vice versa
assert( EnumString< FORM >::To( f, str ) );
Il n'y a pas de "méthode intégrée", mais il existe des moyens d'y parvenir en stockant la paire nom-valeur dans un tableau.
enum myEnum
{
enumItem0,
enumItem1,
enumItem7 = 7,
enumItem8
};
std::vector<std::pair<myEnum,std::string>> gMap;
#define ADDITEM(x) gMap.Push_back(std::pair<myEnum,std::string>(x,#x));
.....
ADDITEM(enumItem0);
ADDITEM(enumItem1);
ADDITEM(enumItem7);
ADDITEM(enumItem8);
Vous pouvez utiliser la macro pour éviter de vous répéter. Voici le tour: Enums, Macros, Unicode et Token-Pasting
En bref: il n'y en a pas. En C++, les énumérations sont des valeurs statiques et non des objets comme en C #. Je vous suggère d'utiliser une fonction avec certaines instructions if else
.
Bien qu'il n'y ait pas de solution directe, il existe quelques solutions de contournement possibles.
Jetez un oeil à cette question: Un moyen facile d'utiliser des variables de types enum comme chaîne dans C?
cela a fonctionné pour moi:
enum NODES { Cone = 1, BaseColor = 2, NONE = 0 };
std::map<std::string, NODES> nodeMap;
nodeMap["Cone"] = NODES::Cone;
nodeMap["BaseColor"] = NODES::BaseColor;
Ce n'est pas possible car les noms ne sont pas disponibles au moment de l'exécution. Lors de la compilation, chaque énumération est remplacée par la valeur entière correspondante.
"Question supplémentaire: Est-il possible de gérer des chaînes indéfinies? Je veux dire que si j'essaie d'obtenir la valeur pour responseHeaderMap [" cookie "], quelle sera la valeur? (À condition que" cookie "ne soit pas défini dans le responseHeaderMap - bart s 22 novembre 16 à 12:04 "
eh bien, vous pouvez juste vérifier avant:
auto it = responseHeaderMap.find("cookie");
if (it != responseHeaderMap.end())
{
// "cookie" exist, can take value
}
Après vérification du "cookie", vous pouvez l’obtenir avec la valeur suivante:
responseHeaderMap["cookie"]
espérons que cette aide
Non, vous devrez utiliser une construction if/then ou utiliser une carte, une table de hachage ou un autre type de structure de données associative pour faciliter cette opération.