如何在C ++ 11中输出枚举类的值
我怎样才能输出在C + + 11中的enum class
的值? 在C + + 03中是这样的:
#include <iostream> using namespace std; enum A { a = 1, b = 69, c= 666 }; int main () { A a = A::c; cout << a << endl; }
在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]'
在Ideone.com编译
与unscoped枚举不同,作用域枚举不能隐式转换为其整数值。 您需要使用cast将其显式转换为整数:
std::cout << static_cast<std::underlying_type<A>::type>(a) << std::endl;
您可能想要将逻辑封装到函数模板中:
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); }
用作:
std::cout << as_integer(a) << std::endl;
#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; }
有可能得到你的第二个例子(即,使用范围枚举的那个)使用与unscoped枚举相同的语法来工作。 此外,该解决scheme是通用的,并且适用于所有范围枚举,而不是为每个范围枚举编写代码(如@ForEveR提供的答案中所示)。
解决的办法是编写一个通用的operator<<
函数,它将适用于任何范围的枚举。 该解决scheme通过std::enable_if
使用SFINAE ,如下所示。
#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; }
(我现在还不能发表评论。)我会build议詹姆斯·麦克奈利斯(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); }
同
-
constexpr
:允许我使用枚举成员值作为编译时数组大小 -
static_assert
+is_enum
:为了确保函数确实编译时间。 与枚举只,如所build议的
顺便说一句,我问自己:为什么我应该使用enum class
当我想为我的枚举成员分配数值?! 考虑到转换工作。
也许我会回到普通的enum
如我在这里build议的: 如何使用枚举作为标志在C + +?
基于@TobySpeight的build议,还有另外一个没有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); }