c++ - 在现代 C++11/C++14/C++17 和 future 的 C++20 中枚举到字符串

标签 c++ string enums c++17 c++20

与所有其他类似问题相反,这个问题是关于使用新的 C++ 特性。

  • 2008 Is there a simple way to convert C++ enum to string?
  • 2008 Easy way to use variables of enum types as string in C?
  • 2008 How to easily map c++ enums to strings
  • 2008 Making something both a C identifier and a string?
  • 2008 Is there a simple script to convert C++ enum to string?
  • 2009 How to use enums as flags in C++?
  • 2011 How to convert an enum type variable to a string?
  • 2011 Enum to String C++
  • 2011 How to convert an enum type variable to a string?
  • 2012 How to convert enum names to string in c
  • 2013 Stringifying an conditionally compiled enum in C

  • 看了很多答案,还是没有找到:
  • 优雅的使用方式 C++11 , C++14C++17新功能
  • 或者在 Boost 中准备好使用的东西
  • 其他计划 C++20

  • 例子
    一个例子通常比一个长的解释更好。
    您可以在 Coliru 上编译并运行此代码段.
    ( Another former example 也可用)
    #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';
    }
    
    约束
  • 请不要无值(value)的重复 other answersbasic link .
  • 请避免臃肿的基于宏的答案,或尽量减少 #define开销尽可能小。
  • 请无说明书enum -> string映射。

  • 很高兴有
  • 支持 enum从一个不为零的数字开始的值
  • 支持负面enum
  • 支持碎片化enum
  • 支持 class enum (C++11)
  • 支持 class enum : <type>有任何允许 <type> (C++11)
  • 编译时(非运行时)转换为字符串,
    或者至少在运行时快速执行(例如 std::map 不是一个好主意...)
  • constexpr (C++11,然后在 C++14/17/20 中放宽)
  • noexcept (C++11)
  • C++17/C++20友好片段

  • 一种可能的想法是使用 C++ 编译器功能在编译时使用基于 variadic template class 的元编程技巧生成 C++ 代码。和 constexpr功能...

    最佳答案

    Magic Enum仅 header 库为 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
    };
    

    有关更多示例,请查看主存储库 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_MINMAGIC_ENUM_RANGE_MAX .
  • MAGIC_ENUM_RANGE_MIN必须小于或等于 0并且必须大于 INT16_MIN .
  • MAGIC_ENUM_RANGE_MAX必须大于 0并且必须小于 INT16_MAX .
  • 如果需要特定枚举类型的另一个范围,请为必要的枚举类型添加特化 enum_range。

    #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;
    };
    }
    
  • 关于c++ - 在现代 C++11/C++14/C++17 和 future 的 C++20 中枚举到字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28828957/

    相关文章:

    c++ - Project Euler #1 测试扩展

    c++ - 如何在 ios 设备中写入日志文件?

    regex - 如何使用 sed 去掉最后一个字符?

    ruby - 字符串文字中的转义状态作为 `String#tr` 的参数

    objective-c - 你如何将 Swift 结构/枚举合并到 Objective-C 中?

    PostgreSQL - 返回任何 ENUM 标签的函数

    c++ - 在 C++ 中实现全局应用程序设置

    c++ - 引用 static_cast 的引用和指向 static_cast 指针的指针的成本

    c++ - 就时间复杂度而言,可以更快地找到另一个字符串中的最小周期字符串吗

    c++ - 奇怪的编译器错误