C++ 打印enum class枚举类

前言

C++11 中引入了强类型的 enum class 类型(或称为枚举类),但是有一点比较尴尬的是,std::cout 标准流不支持输出 enum class 类型。

比如以下代码:

#include <iostream>
 
int main()
{
    enum class Color { red, green = 20, blue };
    Color r = Color::blue;
 
    std::cout << r;
}

在编译时,会有报错,GCC 编译错误信息:

main.cpp:8:14: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'main()::Color')
    8 |     std::cout<<r;
      |     ~~~~~~~~~^~~
      |          |     |
      |          |     main()::Color
      |          std::ostream {aka std::basic_ostream<char>}

MSVC编译错误信息:

E0349	没有与这些操作数匹配的 "<<" 运算符

那么,如何打印 enum class 呢?

解决方案

方法一

enum class 底层类型其实是 int 类型,那么我们可以直接进行强制类型转换即可:

enum class Color { red, green = 20, blue };
Color r = Color::blue;

std::cout<< static_cast<int>(r) << std::endl;
// 或者
std::cout<< static_cast<typename std::underlying_type<Color>::type>(r) << std::endl; 

// 输出:21

方法二

每次都要强制类型转换,太麻烦了,还有更方便点的办法吗?当然有!可以通过重载 operator<< 操作符实现:

std::ostream& operator << (std::ostream& os, const Color& obj)
{
   os << static_cast<std::underlying_type<Color>::type>(obj);
   return os;
}

这样就可以直接使用 std::cout 打印,而不需要先强制转换一次。

std::cout<< r << std::endl;

方法三

如果我有多个 enum class 呢,比如 enum Colorenum Fruit,那我岂不是都要重载 operator<< 操作符一次?所以这里使用 C++黑魔法 SFINAE 从而泛型支持任何枚举类,而不限定于某特定的枚举类:

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

例子:

#include <iostream>
#include <type_traits>

// Scoped enum
enum class Color
{
    Red,
    Green,
    Blue
};

// Unscoped enum
enum Orientation
{
    Horizontal,
    Vertical
};

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";
    return 0;
}

总结

在 C++11中,由于枚举类(enum class)无法直接输出到 std::cout 标准流的问题,为了解决这个问题,提供了三种解决方案。

  1. 第一种解决方案是通过强制类型转换将枚举类转换为底层的 int 类型,然后输出 int 值。
  2. 第二种解决方案是通过重载 operator<< 操作符,将枚举类转换为底层类型后输出。
  3. 第三种解决方案是使用 C++的 SFINAE 技术,通过泛型支持任何枚举类,并将枚举类转换为底层类型后输出。

这些解决方案都可以解决无法直接输出枚举类的问题,并提供了不同的选择和灵活性。

原文链接:C++ 打印enum class枚举类 (limuran.top)

How can I output the value of an enum class in C++11 - Stack Overflow

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值