枚举与强types的枚举

我是C ++编程的初学者。

今天我遇到了一个新的话题:强typesenum 。 我已经研究了一下,但是直到现在我还是无法知道为什么我们需要这个,有什么用呢?

例如,如果我们有:

 enum xyz{a, b, c}; /*a = 0, b = 1, c = 2, (Typical C format)*/ 

为什么我们需要写:

 enum class xyz{a, b, c}; 

我们在这里做什么? 我最重要的疑问是如何使用它。 你能提供一个小例子,这会让我明白。

OK,第一个例子:旧式的枚举没有自己的范围:

 enum Animals {Bear, Cat, Chicken}; enum Birds {Eagle, Duck, Chicken}; // error! Chicken has already been declared! enum class Fruits { Apple, Pear, Orange }; enum class Colours { Blue, White, Orange }; // no problem! 

其次,它们隐含地转换为整数types,这会导致奇怪的行为:

 bool b = Bear && Duck; // what? 

最后,您可以指定C ++ 11枚举的基本整型:

 enum class Foo : char { A, B, C}; 

以前,没有指定底层types,这可能会导致平台之间的兼容性问题。 编辑在注释中已经指出,你也可以在C ++ 11中指定一个“旧式”枚举的底层整型。

在这个IBM页面上有一篇关于枚举的好文章,它非常详细,写得很好。 以下是一些重要的观点:

范围枚举解决了常规枚举所带来的大部分限制:完整的types安全性,明确的基础types,范围问题和前向声明。

  • 您通过禁止范围枚举的所有隐式转换为其他types来获得types安全性。
  • 你得到一个新的范围,枚举不再在封闭范围内,从名称冲突保存自己。
  • 作用域枚举使您能够指定枚举的基础types,对于作用域枚举,如果您select不指定它,则默认为int。
  • 任何具有固定基础types的枚举都可以被前向声明。

enum class值实际上是types的enum class ,而不是C – 枚举types的underlying_typetypes。

 enum xyz { a, b, c}; enum class xyz_c { d, f, e }; void f(xyz x) { } void f_c(xyz_c x) { } // OK. f(0); // OK for C++03 and C++11. f(a); // OK with C++11. f(xyz::a); // ERROR. f_c(0); // OK. f_c(xyz_c::d); 

枚举范围

枚举将其枚举器导出到周围的范围。 这有两个缺点。 首先,如果在同一范围内声明的不同枚举中的两个枚举器具有相同的名称,则会导致名称冲突。 其次,不可能使用具有完全限定名称的枚举器,包括枚举名称。

 enum ESet {a0, a, a1, b1, c3}; enum EAlpha{a, b, c} select = ESet::a; // error select = a; // is ambigious 

枚举类(“新枚举”,“强枚举”)解决了传统C ++枚举的三个问题:

  1. 常规enums隐式转换为int ,导致错误,当有人不希望枚举作为一个整数。
  2. 常规enums将其enums导出到周围的范围,导致名称冲突。
  3. 不能指定enum的基础types,导致混淆,兼容性问题,并使前向声明变得不可能。

enum class (“强枚举”)是强types和范围:

 enum Alert { green, yellow, orange, red }; // traditional enum enum class Color { red, blue }; // scoped and strongly typed enum // no export of enumerator names into enclosing scope // no implicit conversion to int enum class TrafficLight { red, yellow, green }; Alert a = 7; // error (as ever in C++) Color c = 7; // error: no int->Color conversion int a2 = red; // ok: Alert->int conversion int a3 = Alert::red; // error in C++98; ok in C++11 int a4 = blue; // error: blue not in scope int a5 = Color::blue; // error: not Color->int conversion Color a6 = Color::blue; // ok 

如图所示,传统枚举像往常一样工作,但您现在可以select使用枚举的名称。

新枚举是“枚举类”,因为它们将传统枚举(名称值)与方面(范围成员和没有转换)的方面结合在一起。

能够指定基础types允许更简单的互操作性和枚举的保证大小:

 enum class Color : char { red, blue }; // compact representation enum class TrafficLight { red, yellow, green }; // by default, the underlying type is int enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U }; // how big is an E? // (whatever the old rules say; // ie "implementation defined") enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U }; // now we can be specific 

它还可以提前声明枚举:

 enum class Color_code : char; // (forward) declaration void foobar(Color_code* p); // use of forward declaration // ... enum class Color_code : char { red, yellow, green, blue }; // definition 

基础types必须是有符号或无符号整数types之一; 默认是int

在标准库中, enum类用于:

  1. 映射系统特定的错误代码:在<system_error>enum class errc ;
  2. 指针安全指标:在<memory>enum class pointer_safety { relaxed, preferred, strict };
  3. I / Ostream错误:在<iosfwd>enum class io_errc { stream = 1 };
  4. asynchronous通信error handling:在<future>enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied };

其中几个有运营商,如==定义。