我怎样才能输出枚举类的在C ++ 11的值(How can I output the value o

2019-06-14 19:36发布

我怎么能输出的值enum class在C ++ 11? 在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

Answer 1:

不像无作用域枚举,一个范围的列举不是隐式转换为它的整数值。 您需要明确地将其转换为使用强制的整数:

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;


Answer 2:

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


Answer 3:

它可以让你的第二个例子中(即使用范围的枚举的一个)使用相同的语法未范围枚举工作。 此外,该解决方案是通用的,将工作的所有范围的枚举,相对于编写代码对于每个作用域枚举(如图中答案提供@ForEveR )。

解决的办法是写一个通用的operator<<功能,适用于任何范围的枚举工作。 该解决方案采用SFINAE经由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;
}


Answer 4:

(我不能没有发表评论。)我建议如下改进詹姆斯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 :以“确保”编译时该函数可以做某事。 用枚举而已,至于建议

通过我在问自己的方式:为什么我要永远使用enum class时,我想数字值分配给我的枚举成员? 考虑转换工作。

也许我会再回到普通的enum ,我这里建议: 如何使用枚举在C ++的标志吗?


然而,它的另一个(更好)风味,而没有static_assert,基于@TobySpeight的建议:

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);
}


Answer 5:

写简单,

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

int value = static_cast<int>(Color::Blue); // 111


文章来源: How can I output the value of an enum class in C++11