Comments 22
А зачем так сложно и много кода? Если достаточно 1-й шаблонной сущности, с 2-мя map-ми внутри, и 3-я методами наружу: to_string, from_string и insert?
накидай примерно как это будет выглядеть? :)
Лучше даже без insert, а задавать соответствие в конструкторе и, разумеется, нужно добавить проверку ключа в to_string/from_string и добавить к ним const квалификатор:
Код
#include <iostream>
#include <map>
#include <string>
#include <initializer_list>
template<class T>
class EnumMap
{
private:
std::map<T, std::string> _to_string;
std::map<std::string, T> _from_string;
public:
EnumMap(const std::initializer_list<std::pair<T, std::string>> & init_list)
{
for (auto &item : init_list)
{
_to_string[item.first] = item.second;
_from_string[item.second] = item.first;
}
}
std::string to_string(T value)
{
return _to_string[value];
}
T from_string(const std::string & value)
{
return _from_string[value];
}
};
enum A
{
A_ZERO,
A_ONE,
A_TWO
};
EnumMap<A> amap =
{
{A_ZERO, "zero"},
{A_ONE, "one"},
{A_TWO, "two"}
};
enum B
{
B_CAR,
B_BUS,
B_PLANE
};
EnumMap<B> bmap =
{
{B_CAR, "car"},
{B_BUS, "bus"},
{B_PLANE, "plane"}
};
int main(int argc, char *argv[])
{
std::cout << amap.from_string("zero") << std::endl;
std::cout << amap.to_string(A_TWO) << std::endl;
std::cout << bmap.to_string(B_PLANE) << std::endl;
std::cout << bmap.from_string("bus") << std::endl;
return 0;
}
Напоминает "Эволюция программиста на примере «Hello world»".
Проще реализовать так:
Проще реализовать так:
enum TestEnum{
fruit_apple = 0,
fruit_banana,
fruit_mango,
fruit_orange,
};
static const char * TestEnumStrings[] = {
"fruit_apple",
"fruit_banana",
"fruit_mango",
"fruit_orange"
};
std::string toString(const TestEnum &fruit){
return TestEnumStrings[fruit];
};
Не спорю, что проще, но в этом варианте лечге запутаться, если будешь вдруг переставлять значения enum'ов местами.
Да, но есть еще вариант с препроцессором и отдельным файлом: stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c
Но этот способ для огромных списков, ради которых не жалко и файл создать.
Есть еще Boost Preprocessor, в котором наверное можно сделать это препроцессором без отдельного файла. Что-то вроде этого: stackoverflow.com/questions/5530248/creating-a-string-list-and-an-enum-list-from-a-c-macro
Но этот способ для огромных списков, ради которых не жалко и файл создать.
Есть еще Boost Preprocessor, в котором наверное можно сделать это препроцессором без отдельного файла. Что-то вроде этого: stackoverflow.com/questions/5530248/creating-a-string-list-and-an-enum-list-from-a-c-macro
а что если надо перечисления держать в заголовочном файле отдельно от массива строк, генерируемого препроцессором?
С какой целью?
Нет ни какой цели. Просто данность. Библиотека сторонняя предоставляет перечисление, например.
Недавно, был такой же пост, но только с динамическим отображением.
Я автору той статьи, как раз предложил статический вариант. Можете посмотреть для себя, как еще один вариант.
Я автору той статьи, как раз предложил статический вариант. Можете посмотреть для себя, как еще один вариант.
Если есть возможность делать на Boost, то вполне можно обойтись Boost.Bimap + Boost.assign — конструировать bimap статически
В Студии, до 2013 включительно, viewMapOf не потокобезопасен.
Чёт тут до фига лишнего, вот первое же решение что пришло мне в голову (для тех кто не боится макросов)
codepad.org/luPlZX0X
И оно довольно легко расширяется
codepad.org/luPlZX0X
И оно довольно легко расширяется
Немного вводит в заблуждение «статичное» в заголовке. Я ожидал увидеть отображение начала компиляции, а тут однако инициализируется set сначала.
О господи, ну зачем так сложно?! Вот вам кодогенератор серелизатора енумов, вставьте его в любимую систему сборки и добавьте один инклюд где хотите, и не надо никакой темплейтно-макросовой жести.
Sign up to leave a comment.
Расширяемые отображения любых типов значений без использования макросов