我是一个C++编程的初学者。
今天我接触到了一个新的主题:强类型enum
。我进行了一些研究,但到目前为止,我仍然无法找出为什么我们需要它以及它的用途是什么?
例如如果我们有:
enum xyz{a, b, c};
/*a = 0, b = 1, c = 2, (Typical C format)*/
为什么我们需要写:
enum class xyz{a, b, c};
我们在这里尝试做什么? 我最重要的疑问是如何使用它。 你能提供一个小例子,让我理解一下吗?
好的,首先是一个例子:旧版的枚举类型没有自己的作用域:
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页面上有一篇关于枚举(enum)的好文章,详细又写得很好。以下是一些重要的要点:
作用域枚举解决了常规枚举所遇到的大部分限制:完全类型安全、明确定义的底层类型、作用域问题和前向声明。
enum class
的值实际上是 enum class
类型的,而不是像 C 中的枚举那样是 underlying_type
类型的。
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 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 };
其中几个具有运算符,例如定义了 ==
运算符。
枚举范围
枚举将它们的枚举值导出到周围的范围。这有两个缺点。首先,如果在同一作用域中声明的两个不同枚举中有相同名称的枚举值,则可能导致名称冲突; 其次,无法使用包括枚举名称在内的完全限定名称来使用枚举值。
enum ESet {a0, a, a1, b1, c3};
enum EAlpha{a, b, c}
select = ESet::a; // error
select = a; // is ambigious
enum class Colours
和enum class Fruits
吗?因为当我在VS 2010中编写代码时,它会在class
下面抛出一个错误“期望定义或标记名称”。 - Rasmi Ranjan Nayak