Traditional enum in C++¶
1
2
3
4
5
6
7
8
|
enum Week {Mon ,Tue ,Wed ,Thu };
enum Season {Sprint,Summer,Fall ,Winter};
Week w = Tue;
Season s = Summer;
bool isEqual = (w == s); // isEqual is true
}
|
Problem¶
非类型安全,比如对Week w
和Season s
两个逻辑意义上不同类型的变量作比较,会产生不合逻辑的结果:w == s
是 true
。
It’s not safe, the result of w == s
is true
is not reasonalbe.
不同类型的 enum 比较会有编译警告warning
,但只是警告:
1
2
3
|
warning: comparison between ‘enum Week’ and ‘enum Season’ [-Wenum-compare]
| bool isEqual = (w == s);
| ^
|
Scoped enum¶
enum class
and enum struct
are the same
enum class
is not a class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include <iostream>
using namespace std;
namespace EnumOnly {
enum Week { Mon, Tue, Wed, Thu };
enum Season { Sprint, Summer, Fall, Winter };
} // namespace EnumOnly
namespace EnumClass {
enum class Month { Jan, Feb, Mar, Apr };
enum class Num { One=1, Two, Three, Four };
} // namespace EnumClass
int main() {
cout << "EnumOnly::Week::Mon = " << EnumOnly::Week::Mon << endl;
cout << "EnumClass::Month::Jan = " << static_cast<int>(EnumClass::Month::Jan) << endl;
cout << "Is EnumOnly::Week a class : " << std::is_class<EnumOnly::Week>::value << endl;
cout << "Is EnumOnly::Week a enum : " << std::is_enum<EnumOnly::Week>::value << endl;
cout << "Is EnumClass::Month a class : " << std::is_class<EnumClass::Month>::value << endl;
cout << "Is EnumClass::Month a enum : " << std::is_enum<EnumClass::Month>::value << endl;
EnumOnly::Week w = EnumOnly::Tue;
EnumOnly::Season s = EnumOnly::Summer;
EnumClass::Month m = EnumClass::Month::Feb;
EnumClass::Num n = EnumClass::Num::Two;
EnumClass::Num n2 = static_cast<EnumClass::Num>(2);
EnumClass::Num n3 = EnumClass::Num::Three;
if (w == s) {
cout << "w == s, ohh!" << endl; // unmeaningful
} else {
cout << "w != s" << endl;
}
if (n == n2) {
cout << "n == n2, yes" << endl;
} else {
cout << "n != n2, why" << endl;
}
if (n == n3) {
cout << "n == n3" << endl;
} else {
cout << "n != n3, yes" << endl;
}
/*
if (w == m) {
cout << "w == m";
} else {
cout << "w != m";
}
*/
return 0;
}
|
输出如下:
1
2
3
4
5
6
7
8
9
|
EnumOnly::Week::Mon = 0
EnumClass::Month::Jan = 0
Is EnumOnly::Week a class : 0
Is EnumOnly::Week a enum : 1
Is EnumClass::Month a class : 0
Is EnumClass::Month a enum : 1
w == s, ohh!
n == n2, yes
n != n3, yes
|
如果用 ==
比较两个不同类型的 enum class
对象会产生编译错误。
比如用if (w == m)
比较 enum Week
类型的 w
与 enum class Month
类型的 m
会产生如下错误 error
:
1
2
3
4
5
6
|
error: no match for ‘operator==’ (operand types are ‘EnumOnly::Week’ and ‘EnumClass::Month’)
| if (w == m) {
| ~ ^~ ~
| | |
| | EnumClass::Month
| EnumOnly::Week
|
用 ==
比较两个不同的 enum class
对象也会产生相同的编译错误。