В моих значениях перечисления проекта часто требуется выписывать файлы журналов или сохраняться в виде строк. Таким образом, я был обеспечение функции ToString и StringToEnum как в следующих примерах:Как выбрать перегрузку на основе типа возврата
namespace Mine
{
enum class Color { red, green, blue };
inline std::wstring ToString(Color c)
{
switch (c)
{
case Color::red: return L"red";
case Color::green: return L"green";
case Color::blue: return L"blue";
default: THROW_MACRO("Unexpected value[{}] for enum[{}]", c, L"Color");
}
}
inline void StringToEnum(const std::wstring& inEnumValueName, Color& out)
{
if (inEnumValueName == L"red")
{
out = Color::red;
}
else if (inEnumValueName == L"green")
{
out = Color::green;
}
else if (inEnumValueName == L"blue")
{
out = Color::blue;
}
else
{
THROW_MACRO("Unexpected value[{}] for enum[{}]", inEnumValueName, L"Color");
}
}
}
Когда я использую StringToEnum я заканчиваю писать:
Color c;
StrintToEnum(L"red", c);
// use c
Мне бы очень хотелось, чтобы иметь возможность объявить и инициализации в одной строке и написать:
auto c = ToEnum<Mine::Color>(L"red);
Я определил ToEnum, как это и поместить его в заголовок, чтобы быть включены:
namespace CommonCode
{
template<class T>
T ToEnum(const std::wstring& enumValueName)
{
T value;
StringToEnum(enumValueName, value);
return value;
}
}
Проблема заключается в том, что ToEnum не удается скомпилировать, поскольку соответствующие функции StringToEnum не были определены до его появления.
Есть ли полезный способ, которым это может быть закодировано, или я придерживаюсь необходимости писать две строки кода всякий раз, когда я хочу объявить и инициализировать значение перечисления из строки?
Я попытался специализировать ToEnum, но у меня возникла проблема, связанная с тем, что мне нужно закрыть пространство имен. Я определяю enum in, откройте пространство имен CommonCode и добавьте к нему, а затем вернитесь к исходному пространству имен еще раз. Это много печатает и выглядит довольно уродливо.
(Я использую Visual Studio 2015 Update 3, поэтому любые решения, которые скомпилируются с этим, будут предпочтительнее).
Я не уверен, что понимаю, почему вы не можете заставить 'StringToEnum' просто возвращать' Цвет', а не передавать ссылку. – TartanLlama
@TartanLlama, потому что это возможно только для 'Color'. Невозможно было бы использовать для других перечислений. –
Непонятно, почему: a) 'StringToEnum' не может вернуть цвет сам. б) почему он не может быть объявлен перед шаблоном ToEnum. – SergeyA