All streams
Search
Write a publication
Pull to refresh

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;
}

Тут используешь 2-а списка + неудобно то, что надо указывать сам контейнер. Если добавить функционал перегрузки, избавляющий от необходимости «знать» переменную контейнера, то получиться тоже самое, что и в данной статье :)
Напоминает "Эволюция программиста на примере «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
а что если надо перечисления держать в заголовочном файле отдельно от массива строк, генерируемого препроцессором?
Нет ни какой цели. Просто данность. Библиотека сторонняя предоставляет перечисление, например.
Да, в таком случае понадобится способ, описанный автором. Менее продвинутые (или более ленивые) программисты создадут класс с 2 стандартными мапами и пару функций, либо вообще массив и простой поиск, если не критично.
Недавно, был такой же пост, но только с динамическим отображением.
Я автору той статьи, как раз предложил статический вариант. Можете посмотреть для себя, как еще один вариант.
да, увидев тот пост — решил свой вариант изложить — в общую копилку так сказать )
Если есть возможность делать на Boost, то вполне можно обойтись Boost.Bimap + Boost.assign — конструировать bimap статически
В Студии, до 2013 включительно, viewMapOf не потокобезопасен.
Чёт тут до фига лишнего, вот первое же решение что пришло мне в голову (для тех кто не боится макросов)
codepad.org/luPlZX0X
И оно довольно легко расширяется
А где обратное преобразование из строки в значение?
свернуть это все через BOOST_PP и будет все еще красивее чем в посте.
Немного вводит в заблуждение «статичное» в заголовке. Я ожидал увидеть отображение начала компиляции, а тут однако инициализируется set сначала.
да, верно подметили — подкорректировал заголовок
О господи, ну зачем так сложно?! Вот вам кодогенератор серелизатора енумов, вставьте его в любимую систему сборки и добавьте один инклюд где хотите, и не надо никакой темплейтно-макросовой жести.
Sign up to leave a comment.

Articles