将枚举类变量名解析为字符串

Ten*_*czS 8 c++ reflection enums c++11 c++17

考虑一下,我有以下enum课程:

enum class TestEnum
{
   None = 0,
   Foo,
   Bar
};
Run Code Online (Sandbox Code Playgroud)

我想指定ostream operator ( << )这个enum类,所以我可以写:

std::cout << "This is " << TestEnum::Foo;
Run Code Online (Sandbox Code Playgroud)

并得到以下输出This is Foo。

我的问题是:
是否有存储枚举“名称说明符”的地方?(即对于enum class TestEnum 来说,它是None,Foo和Bar)所以我可以编写一个函数(或最多是函数模板)来指定ostream运算符,如下所示TestEnum:

std::ostream& operator<< ( std::ostream& os, TestEnum aEnum ) {
   return std::string( aEnum.name() );
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我是这样做的:

std::ostream& operator<< ( std::ostream& os, TestEnum aEnum ) {
   switch( aEnum )
   {
   case TestEnum::Foo:
       os << "Foo";
       break;
   case TestEnum::Bar:
       os << "Bar"
       break;
   }
   return os;
}
Run Code Online (Sandbox Code Playgroud)

我见过一些使用boost库的解决方案,但这次我不想使用它。

use*_*570 7

是否有存储枚举“名称说明符”的地方?

不,但一种选择是使用std::map<TestEnum, std::string>如下所示:

enum class TestEnum
{
   None = 0,
   Foo,
   Bar
};
const std::map<TestEnum,std::string> myMap{{TestEnum::None, "None"}, 
                                     {TestEnum::Foo, "Foo"}, 
                                     {TestEnum::Bar, "Bar"}};
    
std::ostream& operator<< ( std::ostream& os, TestEnum aEnum )
{
   os << myMap.at(aEnum);
   return os;
}
int main()
{
    std::cout << "This is " << TestEnum::Foo; //prints This is Foo 
    std::cout << "This is " << TestEnum::Bar; //prints This is Bar

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

演示

  • 我认为“string_view”在这里可能更相关。另外,“map”可能应该是“const”,以避免“operator[]”进行不必要的修改。 (3认同)

JeJ*_*eJo 6

是否有存储枚举“名称说明符”的地方?

不,名称不会保存在任何地方。如果需要,需要(不幸的是)对它们进行映射。

如果这些enum值可用于数组索引(如 OP 的情况),则可以使用 array of 进行映射std::string_view(需要或更高版本,否则为 array of std::strings)。

数组的使用使得以下解决方案变得轻量级且 O(1) 查找。

#include <iostream>
#include <string_view>
#include <type_traits> // std::underlying_type_t
using namespace std::string_view_literals;

enum struct TestEnum { None = 0,   Foo,   Bar };
inline static constexpr std::string_view enumArray[]{"None"sv, "Foo"sv, "Bar"sv};

std::ostream& operator<< (std::ostream& os, TestEnum aEnum)
{
    return os << enumArray[static_cast<std::underlying_type_t<TestEnum>>(aEnum)];
}

int main()
{
    std::cout << "This is " << TestEnum::Foo; // prints: "This is Foo" 
    std::cout << "This is " << TestEnum::Bar; // prints: "This is Bar"
}
Run Code Online (Sandbox Code Playgroud)

查看演示