如何在 C++11 中输出枚举类的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11421432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I output the value of an enum class in C++11
提问by Adi
How can I output the value of an enum class
in C++11? In C++03 it's like this:
如何enum class
在 C++11 中输出 an 的值?在 C++03 中,它是这样的:
#include <iostream>
using namespace std;
enum A {
a = 1,
b = 69,
c= 666
};
int main () {
A a = A::c;
cout << a << endl;
}
in c++0x this code doesn't compile
在 c++0x 中,此代码无法编译
#include <iostream>
using namespace std;
enum class A {
a = 1,
b = 69,
c= 666
};
int main () {
A a = A::c;
cout << a << endl;
}
prog.cpp:13:11: error: cannot bind 'std::ostream' lvalue to 'std::basic_ostream<char>&&'
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ostream:579:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = A]'
compiled at Ideone.com
在Ideone.com编译
回答by James McNellis
Unlike an unscoped enumeration, a scoped enumeration is not implicitlyconvertible to its integer value. You need to explicitlyconvert it to an integer using a cast:
与无作用域枚举不同,有作用域枚举不能隐式转换为其整数值。您需要使用强制转换将其显式转换为整数:
std::cout << static_cast<std::underlying_type<A>::type>(a) << std::endl;
You may want to encapsulate the logic into a function template:
您可能希望将逻辑封装到函数模板中:
template <typename Enumeration>
auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
used as:
用作:
std::cout << as_integer(a) << std::endl;
回答by ForEveR
#include <iostream>
#include <type_traits>
using namespace std;
enum class A {
a = 1,
b = 69,
c= 666
};
std::ostream& operator << (std::ostream& os, const A& obj)
{
os << static_cast<std::underlying_type<A>::type>(obj);
return os;
}
int main () {
A a = A::c;
cout << a << endl;
}
回答by James Adkison
It is possible to get your second example (i.e., the one using a scoped enum) to work using the same syntax as unscoped enums. Furthermore, the solution is generic and will work for all scoped enums, versus writing code for each scoped enum (as shown in the answerprovided by @ForEveR).
可以使用与无作用域枚举相同的语法使您的第二个示例(即使用作用域枚举的示例)工作。此外,该解决方案是通用的,适用于所有范围枚举,而不是为每个范围枚举编写代码(如@ForEveR提供的答案所示)。
The solution is to write a generic operator<<
function which will work for any scoped enum. The solution employs SFINAEvia std::enable_if
and is as follows.
解决方案是编写一个operator<<
适用于任何范围枚举的通用函数。解决方案采用SFINAEvia std::enable_if
,如下所示。
#include <iostream>
#include <type_traits>
// Scoped enum
enum class Color
{
Red,
Green,
Blue
};
// Unscoped enum
enum Orientation
{
Horizontal,
Vertical
};
// Another scoped enum
enum class ExecStatus
{
Idle,
Started,
Running
};
template<typename T>
std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
{
return stream << static_cast<typename std::underlying_type<T>::type>(e);
}
int main()
{
std::cout << Color::Blue << "\n";
std::cout << Vertical << "\n";
std::cout << ExecStatus::Running << "\n";
return 0;
}
回答by yau
(I'm not allowed to comment yet.) I would suggest the following improvements to the already great answer of James McNellis:
(我还不能发表评论。)我建议对 James McNellis 已经很好的答案进行以下改进:
template <typename Enumeration>
constexpr auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
static_assert(std::is_enum<Enumeration>::value, "parameter is not of type enum or enum class");
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
with
和
constexpr
: allowing me to use an enum member value as compile-time array sizestatic_assert
+is_enum
: to 'ensure' compile-time that the function does sth. with enumerations only, as suggested
constexpr
: 允许我使用枚举成员值作为编译时数组大小static_assert
+is_enum
:“确保”该函数在编译时执行某事。按照建议仅使用枚举
By the way I'm asking myself: Why should I ever use enum class
when I would like to assign number values to my enum members?! Considering the conversion effort.
顺便说一句,我问自己:enum class
当我想为枚举成员分配数字值时,为什么要使用它?!考虑到转换工作。
Perhaps I would then go back to ordinary enum
as I suggested here: How to use enums as flags in C++?
也许我会enum
像我在这里建议的那样回归普通:How to use enums as flags in C++?
Yet another (better) flavor of it without static_assert, based on a suggestion of @TobySpeight:
根据@TobySpeight 的建议,它的另一种(更好)风格没有 static_assert:
template <typename Enumeration>
constexpr std::enable_if_t<std::is_enum<Enumeration>::value,
std::underlying_type_t<Enumeration>> as_number(const Enumeration value)
{
return static_cast<std::underlying_type_t<Enumeration>>(value);
}
回答by Audrius Meskauskas
To write simpler,
为了写得更简单,
enum class Color
{
Red = 1,
Green = 11,
Blue = 111
};
int value = static_cast<int>(Color::Blue); // 111
回答by NutCracker
Following worked for me in C++11:
以下在 C++11 中为我工作:
template <typename Enum>
constexpr typename std::enable_if<std::is_enum<Enum>::value,
typename std::underlying_type<Enum>::type>::type
to_integral(Enum const& value) {
return static_cast<typename std::underlying_type<Enum>::type>(value);
}
回答by Earl of Lemongrab
You could do something like this:
你可以这样做:
//outside of main
namespace A
{
enum A
{
a = 0,
b = 69,
c = 666
};
};
//in main:
A::A a = A::c;
std::cout << a << std::endl;