【问题标题】:enum to string in modern C++11 / C++14 / C++17 and future C++20在现代 C++11/C++14/C++17 和未来的 C++20 中枚举到字符串
【发布时间】:2015-05-03 22:28:09
【问题描述】:

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

看了很多答案,还是没找到:

示例

一个例子通常比一个冗长的解释更好。
您可以在 Coliru 上编译和运行这个 sn-p。
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';
}

约束

  • 请不要重复other answersbasic link
  • 请避免臃肿的基于宏的答案,或尽量减少#define 开销。
  • 请不要手动enum -> string 映射。

很高兴拥有

  • 支持enum 值从非零的数字开始
  • 支持负的enum
  • 支持分片的enum
  • 支持class enum (C++11)
  • 支持class enum : &lt;type&gt; 具有任何允许的&lt;type&gt; (C++11)
  • 编译时(而非运行时)转换为字符串,
    或者至少在运行时快速执行(例如std::map 不是一个好主意...)
  • constexpr(C++11,然后在 C++14/17/20 中放宽)
  • noexcept (C++11)
  • C++17/C++20友好的sn-p

一个可能的想法是使用 C++ 编译器功能在编译时使用基于 variadic template classconstexpr 函数的元编程技巧生成 C++ 代码...

【问题讨论】:

  • (也许是主题)看看这个 Qt 相关的博客。 woboq.com/blog/reflection-in-cpp-and-qt-moc.html。描述使用 C++ 反射(提议的标准)替换 Qt 的 moc(元对象编译器)的可能性。
  • N4113: std::enumerator::identifier_v&lt;MyEnum, MyEnum::AAA&gt;
  • 一切都必须用 C++ 解决吗?为字符串表示自动生成代码非常容易,只需几行代码。
  • “如果可能,请不要提供基于 C 宏的答案”好吧,除非您愿意等待 C++17,否则几乎没有任何可用的东西,而且它不是 /i> 将枚举声明为DEC_ENUM(enumname, (a,b,c,(d,b),(e,42))) 是不好的,除非您必须维护生成宏......而且恕我直言,将这种情况放入语言中只是另一种黑客行为,而不是更强大的模板/宏混合体。我们不应该将所有有用的宏用例添加到语言中,只是为了能够说宏不再有用。
  • @olibre 这个问题今天至少有两个可用的答案。 1. @ecatmur 关于 C++17 的好回答,我们不能每次在 C++17 讨论中有更新时都对其进行编辑。请参阅mailing list of the reflection study group。 2. 我对当前 C++ 的语法很好的回答,许多人在生产中使用它,但在内部使用 #define。您所要求的是一个可用的解决方案。今天正确的答案是完全“正确”的解决方案要等到以后才可用(即现在接受@ecatmur)。

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


【解决方案1】:

你可以使用select()函数,其实只是一个简写开关;这不是真正意义上的解决方案,但它让生活更轻松:

enum
{
  NORMAL,
  INVALID
} state(NORMAL);

//std::cout << (state ? "INVALID" : "NORMAL") << std::endl;
std::cout << select(state, "NORMAL", "INVALID") << std::endl;

select() 函数在 SIMD/GPU 编程中很常见。它们是三元 ?: 运算符的推广。您还可以将select() 视为函数数组(实现数组数据结构的函数)。

这是完整的example

【讨论】:

    猜你喜欢
    • 2014-02-22
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多