我是C ++编程的初学者。
今天,我遇到了一个新主题:强类型enum
。我已经研究了一下,但是到现在为止我仍无法找出为什么我们需要它,以及它的用途是什么?
例如,如果我们有:
enum xyz{a, b, c};
/*a = 0, b = 1, c = 2, (Typical C format)*/
我们为什么需要写:
enum class xyz{a, b, c};
我们要在这里做什么?我最重要的疑问是如何使用它。您能否提供一个小例子,这会让我理解。
我是C ++编程的初学者。
今天,我遇到了一个新主题:强类型enum
。我已经研究了一下,但是到现在为止我仍无法找出为什么我们需要它,以及它的用途是什么?
例如,如果我们有:
enum xyz{a, b, c};
/*a = 0, b = 1, c = 2, (Typical C format)*/
我们为什么需要写:
enum class xyz{a, b, c};
我们要在这里做什么?我最重要的疑问是如何使用它。您能否提供一个小例子,这会让我理解。
Answers:
好,第一个示例:旧式枚举没有自己的范围:
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!
其次,它们隐式转换为整数类型,这可能导致奇怪的行为:
bool b = Bear && Duck; // what?
最后,您可以指定C ++ 11枚举的基础整数类型:
enum class Foo : char { A, B, C};
以前,未指定基础类型,这可能会导致平台之间的兼容性问题。编辑注释中已经指出,您还可以在C ++ 11中指定“旧式”枚举的基础整数类型。
在此IBM页面上有一篇关于枚举的很好的文章,它非常详细且写得很好。简而言之,这是一些重要点:
作用域枚举解决了常规枚举所带来的大多数限制:完整的类型安全性,定义明确的基础类型,作用域问题和前向声明。
枚举类(“新枚举”,“强枚举”)解决了传统C ++枚举的三个问题:
enums
隐式转换为int
,当某人不希望枚举充当整数时会导致错误。enums
上将其枚举器导出到周围的范围,导致名称冲突。enum
无法指定an的基础类型,从而引起混乱,兼容性问题,并使前向声明变得不可能。enum class
(“强枚举”)具有强类型和范围:
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
如图所示,传统枚举可以照常工作,但是您现在可以选择使用枚举的名称进行限定。
新的枚举是“枚举类”,因为它们将传统枚举的各个方面(名称值)与类的各个方面(作用域成员和无转换)结合在一起。
能够指定基础类型允许更简单的互操作性和保证的枚举大小:
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;
// i.e. "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
基础类型必须是有符号或无符号整数类型之一;默认值为int
。
在标准库中,enum
类用于:
<system_error>
:enum class errc
;<memory>
:enum class pointer_safety { relaxed, preferred, strict };
<iosfwd>
:enum class io_errc { stream = 1 };
<future>
:enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied };
其中一些具有运算符,例如==
defined。
enum class Colours
和吗enum class Fruits
?因为当我在VS 2010中编写代码时,它"expects a defination or a tag name"
在下引发了错误class
。