简介

C包含两种枚举:限定作用域和不限定作用域的。C新标准引入了限定作用域的枚举类型。

1. 限定作用域的枚举类型

  1. enum class open_modes {input, output, append};
  2. // 等价
  3. enum struct open_modes {input, output, append};

2. 不限定作用域的枚举类型

  • 省略掉关键字class
  • 枚举名字是可选的
  1. // 不限定作用域的枚举类型
  2. enum color {red, yellow, green};
  3. // 未命名的、不限定作用域的枚举类型
  4. enum {floatPrec = 6, doublePrec = 10, double_doublePrec = 10};

枚举也可以定义新的类型

  1. enum color {red, yellow, green}; // 不限定作用域的枚举类型
  2. enum stoplight {red, yellow, green}; // 错误: 重复定义了枚举成员
  3. enum class peppers {red, yellow, green}; // 正确: 枚举成员被隐藏了
  4. int i = color::red; // 正确: 不限定作用域的枚举类型的枚举成员隐式地转换成int
  5. int j = peppers::red; // 错误: 限定作用域的枚举类型不会进行隐式转换

指定enum的大小

尽管每个enum都定义了唯一的类型,但是实际上enum是由某种整数类型表示的。在C++11新标准中,我们可以在enum的名字后加上冒号以及我们想在该enum使用的类型:

  1. enum intValues : unsigned long long {
  2. charTyp = 255, shortTyp = 65535, intTyp = 65535,
  3. longTyp = 4394967295UL,
  4. long_longTyp = 18446744073709551615ULLL
  5. };

形参匹配与枚举类型

要想初始化一个enum对象,必须使用该enum类型的另一个对象或者它的一个枚举成员。因此,即使某个整型值恰好与枚举成员的值相等,它也不能作为函数的enum实参使用:

  1. // 不限定作用域的枚举类型,潜在类型因机器而异
  2. enum Tokens {INLINE = 128, VIRTUAL = 129};
  3. void ff(Tokens);
  4. void ff(int);
  5. int main() {
  6. Tokens curTok = INLINE;
  7. ff(128); // 精确匹配ff(int)
  8. ff(INLINE); // 精确匹配ff(Tokens)
  9. ff(curTok); // 精确匹配ff(Tokens)
  10. return 0;
  11. }

尽管我们不能将整型值传递给enum形参,但是可以将一个不限定作用域的枚举类型的对象或枚举成员传给整型形参。此时enum的值提升为int或更大的整型,实际提升的结果由枚举类型的潜在类型决定:

  1. void newf(unsigned char);
  2. void newf(int);
  3. unsigned char uc = VIRTUAL;
  4. newf(VIRTUAL); // 调用newf(int)
  5. newf(uc); // 调用newf(unsigned char)