C++

C++11 强枚举类型

关于C++强枚举新特性

Posted by VK on February 20, 2020

C++11 强枚举类型

在标准C++11之前的枚举是继承C的,枚举类型不是类型安全的。枚举类型被视为整数,这使得两种不同的枚举类型之间可以进行比较。

一、C中enum类型的局限语法:

enum type1{a, b, c};
enum type2{a, d, e};

1、非强类型作用域 上面两种不同类型的枚举都含有a枚举常量,在相同作用域会发生冲突,编译会报错 2、允许编译器隐式类型转换 if(type1::a == type2::d){;} 两种不同enum常量比较没有实际意义,但是编译器是先将enum常量转换为int类型后,再比较的,不会报错。 3、占用存储空间极其符号不确定

enum type3{ a = 1, b = 0xFFFFFFFFFLL };
std::cout << sizeof(type3::a) << std::endl;   //可能为8,视编译器而定,由其对齐字长决定的
std::cout << type3::b << std::endl;           //输出大小不定,可能为0

问题来了,存储大小和符号都有未定的因素

二、C++11强枚举类型

语法:

enum struct|class name:type{a, b, c};   //class或struct完全等价,指定底层类型type
enum struct|class name{a, b, c};     //不指定底层类型,默认为int

特点及用法: 1、强作用域

type4 t = type4::a; //必须指定强类型名称
type4 p = a;        //错误

2、不可隐式转换(可强转static_cast)

if(t < type4::b);             //同一个enum类型可以比较
if(t > type5::b);            //非同一个enum类型,不能隐式转换为int等值,不能比较
if((int)t > (int)type5::b)  //强制类型转换,可以通过

3、可以指定底层类型

enum class type6:char{a=1, b=2};
enum class type7:unsigned int{a=0xFFFFFFFF};

既可以节省空间,又可以指定符号 4.C++11是兼容并拓展了C enum类型的

enum type8:char{a=1, b=2};
type8 t =a;

示例代码:

#include <iostream>
 
// enum that takes 16 bits
enum smallenum: int16_t
{
    a,
    b,
    c
};
 
 
// color may be red (value 0), yellow (value 1), green (value 20), or blue (value 21)
enum color
{
    red,
    yellow,
    green = 20,
    blue
};
 
// altitude may be altitude::high or altitude::low
enum class altitude: char   //这里的class可以不要,其实跟enum altitude:char 没啥区别
{ 
     high='h',
     low='l', // C++11 allows the extra comma
}; 
 
// the constant d is 0, the constant e is 1, the constant f is 3
enum
{
    d,
    e,
    f = e + 2
};
 
//enumeration types (both scoped and unscoped) can have overloaded operators
std::ostream& operator<<(std::ostream& os, color c)
{
    switch(c)
    {
        case red   : os << "red";    break;
        case yellow: os << "yellow"; break;
        case green : os << "green";  break;
        case blue  : os << "blue";   break;
        default    : os.setstate(std::ios_base::failbit);
    }
    return os;
}
 
std::ostream& operator<<(std::ostream& os, altitude al)
{
    return os << static_cast<char>(al);
}
 
int main()
{
    color col = red;
    altitude a;
    a = altitude::low;
 
    std::cout << "col = " << col << '\n'
              << "a = "   << a   << '\n'
              << "f = "   << f   << '\n';
}