解析枚举 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
,它是 None
、Foo
和 Bar
) 所以我可以编写一个函数(或最多函数模板)来指定 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;
}
Is there any place where enum "name specifiers" are stored?
不,名字没有保存在任何地方。如果需要,需要(不幸的是)对它们进行映射。
如果 enum
值可用于数组索引(如 OP 的情况),则可以使用 std::string_view
的数组进行映射(需要 c++17 或更高版本,否则为数组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"
}
考虑一下我有以下枚举 class:
enum class TestEnum
{
None = 0,
Foo,
Bar
};
我想为这个枚举指定 ostream operator ( << )
class 这样我就可以写:
std::cout << "This is " << TestEnum::Foo;
并得到以下输出 This is Foo
.
我的问题是:
是否有存储枚举“名称说明符”的地方? (即对于 enum class TestEnum
,它是 None
、Foo
和 Bar
) 所以我可以编写一个函数(或最多函数模板)来指定 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;
}
Is there any place where enum "name specifiers" are stored?
不,名字没有保存在任何地方。如果需要,需要(不幸的是)对它们进行映射。
如果 enum
值可用于数组索引(如 OP 的情况),则可以使用 std::string_view
的数组进行映射(需要 c++17 或更高版本,否则为数组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"
}