如何在C++ 11中输出枚举类的值

Adi*_*Adi 83 c++ enums c++11 enum-class

如何enum class在C++ 11中输出a的值?在C++ 03中,它是这样的:

#include <iostream>

using namespace std;

enum A {
  a = 1,
  b = 69,
  c= 666
};

int main () {
  A a = A::c;
  cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)

在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]'
Run Code Online (Sandbox Code Playgroud)

Ideone.com编译

Jam*_*lis 106

与未作用域的枚举不同,作用域枚举不可隐式转换为其整数值.您需要使用强制转换将其显式转换为整数:

std::cout << static_cast<std::underlying_type<A>::type>(a) << std::endl;
Run Code Online (Sandbox Code Playgroud)

您可能希望将逻辑封装到函数模板中:

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);
}
Run Code Online (Sandbox Code Playgroud)

用作:

std::cout << as_integer(a) << std::endl;
Run Code Online (Sandbox Code Playgroud)

  • 虽然这已经晚了两年,如果有人看到这个问题,你可以使用上面的强制转换技术方法,只需调用"static_cast <int>(value)"来获取整数或"static_cast <A>(intValue)"到获得枚举值.请记住,从int到enum或enum到enum会导致问题,通常通常是设计错误的标志. (9认同)
  • int(value)和A(intValue)也可以工作,没有丑陋的尖括号. (4认同)
  • `as_integer`可以定义为`constexpr`,以便它可以在需要常量表达的上下文中使用. (4认同)
  • 是否有使用尾随返回类型语法的原因? (2认同)
  • @NicolBolas:我从一个开放源代码库CxxReflect中复制了“ as_integer”(请参阅​​[enumeration.hpp](http://cxxreflect.codeplex.com/SourceControl/changeset/view/8ffbb562ad38#cxxreflect%2fcore%2fenumeration。 hpp))。该库在任何地方都一致地使用尾随返回类型。为了一致性。 (2认同)

For*_*veR 37

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Dennis [underlying_type](http://www.cplusplus.com/reference/type_traits/underlying_type/)仅适用于C++ 11 (3认同)

Jam*_*son 19

可以使用与unscoped枚举相同的语法来获取第二个示例(即使用范围枚举的示例).此外,该解决方案是通用的,适用于所有范围的枚举,而不是为每个范围的枚举编写代码(如@ForEveR提供的答案中所示).

解决方案是编写一个通用operator<<函数,该函数适用于任何作用域枚举.该解决方案采用SFINAE via 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;
}
Run Code Online (Sandbox Code Playgroud)


h22*_*h22 12

为了写得更简单,

enum class Color
{
    Red = 1,
    Green = 11,
    Blue = 111
};

int value = static_cast<int>(Color::Blue); // 111
Run Code Online (Sandbox Code Playgroud)


yau*_*yau 9

(我不允许发表评论.)我建议对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);
}
Run Code Online (Sandbox Code Playgroud)

  • constexpr:允许我使用枚举成员值作为编译时数组大小
  • static_assert+ is_enum:'确保'函数执行的编译时间.仅提供枚举,如建议的那样

顺便说一句,我问自己:为什么enum class我想在我的枚举成员中分配数字值时使用?!考虑转换努力.

也许我会enum像我在这里建议的那样回到平凡:如何在C++中使用枚举作为标志?


根据@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);
}
Run Code Online (Sandbox Code Playgroud)