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

c++, c++17, c++20, enums, string

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]`.

By default `MAGIC_ENUM_RANGE_MIN = -128`, `MAGIC_ENUM_RANGE_MAX = 128`.

If need another range for all enum types by default, redefine the macro `MAGIC_ENUM_RANGE_MIN` and `MAGIC_ENUM_RANGE_MAX`.

`MAGIC_ENUM_RANGE_MIN` must be less or equals than `0` and must be greater than `INT16_MIN`.

`MAGIC_ENUM_RANGE_MAX` must be greater than `0` and must be less than `INT16_MAX`.

If need another range for specific enum type, add specialization enum_range for necessary enum type.

#include <magic_enum.hpp>

enum number { one = 100, two = 200, three = 300 };

namespace magic_enum {
template <>
  struct enum_range<number> {
    static constexpr int min = 100;
    static constexpr int max = 300;
};
}

Problem

Contrary to all other similar questions, this question is about using the new C++ features. - 2008 c Is there a simple way to convert C++ enum to string? - 2008 c Easy way to use variables of enum types as string in C? - 2008 c++ How to easily map c++ enums to strings - 2008 c++ Making something both a C identifier and a string? - 2008 c++ Is there a simple script to convert C++ enum to string? - 2009 c++ How to use enums as flags in C++? - 2011 c++ How to convert an enum type variable to a string? - 2011 c++ Enum to String C++ - 2011 c++ How to convert an enum type variable to a string? - 2012 c How to convert enum names to string in c - 2013 c Stringifying an conditionally compiled enum in C After reading many answers, I did not yet find any: - Elegant way using C++11, C++14 or C++17 new features - Or something ready-to-use in Boost - Else something planned for C++20 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 - Please no valueless duplication of other answers or basic link. - Please avoid bloat macro-based answer, or try to reduce the `#define` overhead as minimum as possible. - Please no manual `enum` -> `string` mapping. Nice to have - Support `enum` values starting from a number different from zero - Support negative `enum` values - Support fragmented `enum` values - Support `class enum` (C++11) - Support `class enum : <type>` having any allowed `<type>` (C++11) - Compile-time (not run-time) conversions to a string, or at least fast execution at run-time (e.g. `std::map` is not a great idea...) - `constexpr` (C++11, then relaxed in C++14/17/20) - `noexcept` (C++11) - C++17/C++20 friendly snippet 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...

Original source

Related problems