通过重载运算符输出强类型枚举的值


今年的冬天来的静悄悄的,动静略带痕迹。这让我想起故乡的冬,在我的印象里,故乡的冬似乎总是急匆匆的到来,一场秋雨便将秋送走。回想起那时故乡的入冬时节,人人换上厚衣服,母亲常常会提醒我下周的天气,让我提前带好衣裳。现在回想,那时的时光好像也是这样急匆匆,这样急匆匆地离开。
好的,下面来看看关于“通过重载运算符输出强类型枚举的值”。 例子摘自《现代C++教程:高速上手 C++11141720》

对于下面的枚举类型:

enum class NEW_ENUM : unsigned int 
{
    a,
    b,
    c,
    d = 100,
    e = 100
};

我们可以通过重载运算符输出枚举的值:

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

这样我们就可以通过下面的代码输出枚举的值:

std::cout << NEW_ENUM::a << std::endl;

解释重载过程:

  • template <typename T>
    • 定义一个模板函数,模板参数为类型T。这是为了支持任意类型的枚举。
  • std::ostream& operator << (typename std::enable_if<std::is_enum<T>::value, std::ostream >:: type& stream , const T& e)
    • SFINAE(Substitution Failure Is Not An Error)技术是C++模板元编程中的一个技术。这个技术的核心思想是:如果一个模板函数在实例化时,无法通过编译,那么编译器不会报错,会根据具体的情况选择另一个重载的函数。(个人的一个通俗的理解,如果通过SFINAE机制的函数不满足条件,那么就忽略这个函数。)
    • std::ostream&:返回值为输出流对象的引用。这是为了支持连续输出。
    • operator <<:重载输出运算符。
    • std::enable_if<std::is_enum<T>::value, std::ostream >:: type:这是一个模板元函数,用于判断T是否为枚举类型。如果是枚举类型,返回std::ostream类型,否则返回void。这是为了限制只有枚举类型才能调用这个函数。
      • std::enable_if:模板元函数。这个函数是一个模板函数,有两个模板参数:一个是bool类型的值,另一个是返回值类型。如果第一个参数为true,则返回第二个参数类型,否则返回void。
      • std::is_enum<T>::value:判断T是否为枚举类型。如果是枚举类型,返回true,否则返回false。
      • std::ostream:返回值类型。
      • :: type:返回值类型。
      • stream:输出流对象。是这个函数的第一个参数。表示重载的输出运算符左边的对象。
      • const T& e:枚举对象。是这个函数的第二个参数。表示重载的输出运算符右边的对象。
  • return stream << static_cast<typename std::underlying_type<T>::type>(e);
    • 返回输出流对象。
    • stream << static_cast<typename std::underlying_type<T>::type>(e):输出枚举的值。
      • stream:输出流对象。
      • <<:输出运算符。
      • static_cast<typename std::underlying_type<T>::type>(e):将枚举对象转换为枚举的底层类型。
        • static_cast:类型转换运算符。静态类型转换,不会进行运行时检查。
        • std::underlying_type<T>:获取枚举类型T的底层类型。注意这里的T是枚举类型,不是枚举对象。
        • typename std::underlying_type<T>::type:这里tpyename是一个关键字,表示std::underlying_type<T>::type是一个类型。std::underlying_type<T>::type是枚举类型T的底层类型。
        • 整体的逻辑是:将枚举对象转换为枚举的底层类型,然后输出这个值。
posted @ 2024-12-26 14:38  BryceAi  阅读(15)  评论(0编辑  收藏  举报