c++stringenumsc++17c++20

How to convert an enum to a string in modern C++


Contrary to all other similar questions, this question is about using the new C++ features.

After reading many answers, I did not yet find any:

Example

An example is often better than a long explanation.
You can compile and run this snippet on Coliru.
(Another former example is also available)

#include <map>
#include <iostream>

struct MyClass
{
    enum class MyEnum : char {
        AAA = -8,
        BBB = '8',
        CCC = AAA + BBB
    };
};

// Replace magic() by some faster compile-time generated code
// (you're allowed to replace the return type with std::string
// if that's easier for you)
const char* magic (MyClass::MyEnum e)
{
    const std::map<MyClass::MyEnum,const char*> MyEnumStrings {
        { MyClass::MyEnum::AAA, "MyClass::MyEnum::AAA" },
        { MyClass::MyEnum::BBB, "MyClass::MyEnum::BBB" },
        { MyClass::MyEnum::CCC, "MyClass::MyEnum::CCC" }
    };
    auto   it  = MyEnumStrings.find(e);
    return it == MyEnumStrings.end() ? "Out of range" : it->second;
}

int main()
{
   std::cout << magic(MyClass::MyEnum::AAA) <<'\n';
   std::cout << magic(MyClass::MyEnum::BBB) <<'\n';
   std::cout << magic(MyClass::MyEnum::CCC) <<'\n';
}

Constraints

Nice to have

One possible idea could be using the C++ compiler capabilities to generate C++ code at compilation-time using meta-programming tricks based on variadic template class and constexpr functions...


Solution

  • Magic Enum header-only library provides static reflection for enums (to string, from string, iteration) for C++17.

    (Disclosure: I'm the author of the library.)

    #include <magic_enum.hpp>
    
    enum Color { RED = 2, BLUE = 4, GREEN = 8 };
    
    Color color = Color::RED;
    auto color_name = magic_enum::enum_name(color);
    // color_name -> "RED"
    
    std::string color_name{"GREEN"};
    auto color = magic_enum::enum_cast<Color>(color_name)
    if (color.has_value()) {
      // color.value() -> Color::GREEN
    };
    

    For more examples check home repository https://github.com/Neargye/magic_enum.

    Where is the drawback?

    This library uses a compiler-specific hack (based on __PRETTY_FUNCTION__ / __FUNCSIG__), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9.

    Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX].