Ответ 1
A std::map<std::string, MyEnum>
(или unordered_map
) может сделать это легко. Заполнение карты было бы столь же утомительным, как и оператор switch.
Есть ли простой способ в С++ преобразовать строку в enum (аналогично Enum.Parse
в С#)? Оператор switch будет очень длинным, поэтому мне было интересно, есть ли более простой способ сделать это?
EDIT:
Спасибо за все ваши ответы. Я понял, что для моего конкретного случая существует гораздо более простой способ сделать это. Строки всегда содержали charater 'S', за которым следовало некоторое число, поэтому я просто сделал
int i = atoi(myStr.c_str() + 1);
а затем включил i.
A std::map<std::string, MyEnum>
(или unordered_map
) может сделать это легко. Заполнение карты было бы столь же утомительным, как и оператор switch.
Используйте std::map<std::string, Enum>
и используйте boost::map_list_of
, чтобы легко инициализировать его.
Пример
enum X
{
A,
B,
C
};
std::map<std::string, X> xmap = boost::map_list_of("A", A)("B", B)("C",C);
увидел этот пример где-то
#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(){}
};
Нет встроенного способа, но есть способы достичь этого, сохранив имя-значение пары в массиве
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);
Я использую эти "трюки" > http://codeproject.com/Articles/42035/Enum-to-String-and-Vice-Versa-in-C
После
enum FORM {
F_NONE = 0,
F_BOX,
F_CUBE,
F_SPHERE,
};
вставить
Begin_Enum_String( FORM )
{
Enum_String( F_NONE );
Enum_String( F_BOX );
Enum_String( F_CUBE );
Enum_String( F_SPHERE );
}
End_Enum_String;
Работает отлично, если значения в перечислении не дублируются.
Пример в коде
enum FORM f = ...
const std::string& str = EnumString< FORM >::From( f );
наоборот
assert( EnumString< FORM >::To( f, str ) );
Короче: их нет. В С++ перечисления являются статическими значениями, а не объектами, как в С#. Я предлагаю вам использовать функцию с некоторыми операторами if else
.
Вы можете использовать макрос, чтобы свести к минимуму повторение. Вот трюк: Enums, Macros, Unicode и Token-Вставка
Это невозможно, потому что имена не доступны во время выполнения. Во время компиляции каждое перечисление заменяется на соответствующее целочисленное значение.
Хотя прямого решения нет, существует несколько возможных обходных путей.
Взгляните на этот вопрос: Простой способ использовать переменные типов перечисления как строку в C?
Нет, вам нужно будет использовать конструкцию if/then или использовать карту или хеш-таблицу или какой-либо другой тип ассоциативной структуры данных, чтобы облегчить это.
это сработало для меня:
enum NODES { Cone = 1, BaseColor = 2, NONE = 0 };
std::map<std::string, NODES> nodeMap;
nodeMap["Cone"] = NODES::Cone;
nodeMap["BaseColor"] = NODES::BaseColor;
"Дополнительный вопрос: возможно ли обрабатывать строки undefined? Я имею в виду, если я попытаюсь получить значение для responseHeaderMap [" cookie "], каково будет значение? (при условии, что" cookie "не определен в ответHeaderMap - bart s ноябрь 22 '16 в 12:04"
ну, вы можете просто проверить до этого:
auto it = responseHeaderMap.find("cookie");
if (it != responseHeaderMap.end())
{
// "cookie" exist, can take value
}
После проверки "cookie" вы можете получить его с помощью:
responseHeaderMap["cookie"]
надеюсь, что эта помощь