C++11 FAQ中文版:枚举类——具有类域和强类型的枚举

来源:互联网 发布:淘宝客好用吗 编辑:程序博客网 时间:2024/06/05 21:07

枚举类——具有类域和强类型的枚举

枚举类(“新的枚举”,“强类型的枚举”)主要用来解决传统的C++枚举的三个问题:

  • 可转换的枚举类型默认被转换为int类型,在那些不需要枚举类型表现为int类型的情况下,这可能会导致错误发生
  • 可转换的枚举会使得它的所有枚举值在其周围的代码范围内都是可见的,则可能会导致名字冲突
  • 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解,兼容性问题并且不可以进行前向声明

枚举类(enum)(“强类型枚举”)是强类型的,并且具有类域:

    enum Alert { green, yellow, election, red }; // 传统枚举     enum class Color { red, blue };   // 新的具有类域和强类型的枚举类     // 它的枚举值在类的外部时不可见的     //  不会默认地转换成int     enum class TrafficLight { red, yellow, green };     Alert a = 7;   //  错误,传统枚举不是强类型的,a没有数据类型     Color c = 7;   // 错误,没有默认的 int到Color的转换     int a2 = red;           // 正确,Alert默认转换成int    // 在 C++98中是错误的,但是在C++0x中是正确的    int a3 = Alert::red;    int a4 = blue;            // 错误,blue并没有在类域中     int a5 = Color::blue; // 错误,没有Color到int的默认转换      Color a6 = Color::blue;   // 正确

正如上面的代码所展示的那样,传统的枚举可以照常工作,但是你现在可以通过提供一个类名来改善枚举的使用,使其成为一个强类型的具有类域的枚举。

因为新的具有类名的枚举具有传统的枚举的功能(命名的枚举值),同时又具有了类的一些特点(具有类域的成员和无法进行默认的类型转换),所以我们将其称为枚举类(enum class)。

因为可以指定枚举的底层数据类型,所以可以进行简单的互通操作以及保证枚举值的体积尺寸大小:

enum class Color : char { red, blue }; // compact representation    // 默认情况下,枚举值的底层数据类型为int    enum class TrafficLight { red, yellow, green };       // E的体积是多大呢?    enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U };     // 不管旧的规则怎么说,比如依赖于实现等     // 现在我们可以指定枚举值的底层数据类型    enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U };

同样的,指定枚举值的底层数据类型,使得前向声明(译注:就是在声明定义一个枚举类之前就使用这个枚举类的名字声明变量)成为可能:

enum class Color_code : char;     // (前向) 声明     void foobar(Color_code* p);       // 前向声明的使用     // ...     enum class Color_code : char { red, yellow, green, blue }; // 定义

枚举类的底层数据类型必须是有符号或无符号的整型,默认情况下是int。
标准库中也使用了枚举类。

  • 为了对应特定的系统错误代码,在枚举类errc中
  • 为了安全的指针指示标志,在枚举类pointer_safety { relaxed, preferred, strict }中
  • 为了I/O流错误,在枚举类io_errc { stream = 1 }中
  • 为了处理异步通信错误,在枚举类future_errc { broken_promise, future_already_retrieved, promise_already_satisfied }中

其中的某些枚举类拥有操作符,比如“==”等。

参考:
the C++ draft section 7.2
[N1513=03-0096] David E. Miller: Improving Enumeration Types (original enum proposal).
[N2347 = J16/07-0207] David E. Miller, Herb Sutter, and Bjarne Stroustrup: Strongly Typed Enums (revision 3).
[N2499=08-0009] Alberto Ganesh Barbati: Forward declaration of enumerations.