A fellow engineer at work asked me today how to convert an enum
to a string
value. This is what I came up with:
#include <iostream>
#include <map>
#include <cassert>
enum class MyEnum : int
{
V1,
V2,
V3,
SIZE
};
const char* MyEnumToString(MyEnum e)
{
using MapType = std::map<MyEnum, const char*>;
static const MapType kMap =
{
{ MyEnum::V1, "V1" },
{ MyEnum::V2, "V2" },
{ MyEnum::V3, "V3" },
};
assert(kMap.size() == (int)MyEnum::SIZE);
return kMap.at(e);
}
int main(int argc, char** argv)
{
std::cout << MyEnumToString(MyEnum::V1) << std::endl;
std::cout << MyEnumToString(MyEnum::V2) << std::endl;
std::cout << MyEnumToString(MyEnum::V3) << std::endl;
return 1;
}
MyEnumToString
function has a static map of MyEnum
to const char*
. In the assert
, it checks that the MyEnum::SIZE
is equal to the size of the map: so you don’t forget to update the map when you update MyEnum
with a new entry.
For larger enum
s, would unordered_map
be a better choice for the mapping data structure in terms of performance? Probably.
UPDATE
Several people here and on reddit suggested that the use of std::map
or even std::unordered_map
is an overkill. I agree. Though it is a must for non continuous enum
s (ones that do not start at 0
and do not increment by 1
). Below is an updated MyEnumToString
function which offers much faster conversion. It uses std::array
to hold the string
values.
const char* MyEnumToString(MyEnum e)
{
using MapType = std::array<const char*, (size_t)MyEnum::SIZE>;
static const MapType kMap =
{
"V1",
"V2",
"V3"
};
static_assert(kMap.size() == (size_t)MyEnum::SIZE);
return kMap.at((MapType::size_type)e);
}