解析枚举 class 变量名

resolve enum class variable name

考虑一下我有以下枚举 class:

enum class TestEnum
{
   None = 0,
   Foo,
   Bar
};

我想为这个枚举指定 ostream operator ( << ) class 这样我就可以写:

std::cout << "This is " << TestEnum::Foo;

并得到以下输出 This is Foo.
我的问题是:
是否有存储枚举“名称说明符”的地方? (即对于 enum class TestEnum,它是 NoneFooBar 所以我可以编写一个函数(或最多函数模板)来指定 ostream 这个 TestEnum 的运算符,比如:

std::ostream& operator<< ( std::ostream& os, TestEnum aEnum )
{
   return std::string( aEnum.name() );
}

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

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

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

Is there any place where enum "name specifiers" are stored?

否,但一种选择是使用 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;
}

Demo

Is there any place where enum "name specifiers" are stored?

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

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

数组的使用,使下面的解决方案变得轻量级和 O(1) look-up。

#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"
}

See a demo