在现代 C++11/C++14/C++17 和未来的 C++20 中枚举到字符串
与所有其他类似问题相反,这个问题是关于使用新的 C++ 特性.
- 2008 c 有没有一种简单的方法可以将 C++ 枚举转换为字符串?
- 2008 c 在 C 中使用枚举类型的变量作为字符串的简单方法?
- 2008 c++ 如何轻松地将 C++ 枚举映射到字符串
- 2008 c++ 使某些东西既是 C 标识符又是字符串?
- 2008 c++ 是否有将 C++ 枚举转换为字符串的简单脚本?
- 2009 c++ 如何在 C++ 中使用枚举作为标志?
- 2011 c++ 如何将枚举类型变量转换为字符串?
- 2011 c++ 枚举到字符串 C++
- 2011 c++ 如何将枚举类型变量转换为字符串?
- 2012 c 如何在 c 中将枚举名称转换为字符串
- 2013 c 在 C 中对条件编译的枚举进行字符串化
看了很多答案,我还没有找到:
- 使用 C++11 的优雅方式,C++14 或 C++17 新功能
- 或者在 Boost 中准备使用的东西
- 其他为 C++20 的计划
示例
一个例子往往比一个长的解释要好.
您可以在 Coliru 上编译并运行此代码段.
(另一个前面的例子也是可用的)
#include
限制条件
- 请不要重复其他答案或基本链接.莉>
- 请避免基于宏的臃肿答案,或尽量减少
#define
开销. - 请不要手动
enum
->string
映射.
很高兴有
- 支持
enum
值从非零的数字开始 - 支持负
enum
值 - 支持碎片化的
enum
值 - 支持
类枚举
(C++11) - 支持
class enum :
具有任何允许的
(C++11) - 编译时(非运行时)转换为字符串,
或者至少在运行时快速执行(例如std::map
不是一个好主意......) constexpr
(C++11,然后在 C++14/17/20 中放松)noexcept
(C++11)- C++17/C++20 友好代码段
一个可能的想法是使用 C++ 编译器功能在编译时使用基于 variadic template class
和 constexpr
函数的元编程技巧生成 C++ 代码..
Magic Enum 仅标头库为 C++17 的枚举(到字符串、从字符串、迭代)提供静态反射.
#include 枚举颜色 { 红色 = 2, 蓝色 = 4, 绿色 = 8 };颜色颜色 = 颜色::红色;auto color_name = magic_enum::enum_name(color);//颜色名称 ->红色的"std::string color_name{"GREEN"};自动颜色 = magic_enum::enum_cast(color_name)如果(颜色.has_value()){//color.value() ->颜色::绿色};
有关更多示例,请查看主存储库 https://github.com/Neargye/magic_enum.>
缺点在哪里?
此库使用特定于编译器的 hack(基于 __PRETTY_FUNCTION__
/__FUNCSIG__
),适用于 Clang >= 5、MSVC >= 15.3 和 GCC >= 9.
枚举值必须在 [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]
范围内.
默认
MAGIC_ENUM_RANGE_MIN = -128
,MAGIC_ENUM_RANGE_MAX = 128
.如果所有枚举类型默认需要另一个范围,重新定义宏
MAGIC_ENUM_RANGE_MIN
和MAGIC_ENUM_RANGE_MAX
.MAGIC_ENUM_RANGE_MIN
必须小于或等于0
,并且必须大于INT16_MIN
.MAGIC_ENUM_RANGE_MAX
必须大于0
且必须小于INT16_MAX
.如果需要特定枚举类型的另一个范围,请为必要的枚举类型添加特殊化 enum_range.
#include
枚举数 { 一 = 100, 二 = 200, 三 = 300 };命名空间magic_enum {模板 <>struct enum_range {静态 constexpr int min = 100;静态 constexpr int 最大值 = 300;};}
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) <<'
';
std::cout << magic(MyClass::MyEnum::BBB) <<'
';
std::cout << magic(MyClass::MyEnum::CCC) <<'
';
}
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...
Magic Enum header-only library provides static reflection for enums (to string, from string, iteration) for C++17.
#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
andMAGIC_ENUM_RANGE_MAX
.MAGIC_ENUM_RANGE_MIN
must be less or equals than0
and must be greater thanINT16_MIN
.MAGIC_ENUM_RANGE_MAX
must be greater than0
and must be less thanINT16_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; }; }
相关文章