强枚举类型
原来继承自C语言的枚举类型在C++之父看来是一个奇怪且半生不熟的概念。
枚举的弊端
虽然枚举类型可以避免A类型赋值给B类型,但是:
- 可以直接跨枚举比较
- 可以直接转化为int
- 同名的枚举值是冲突的
虽然有很多缺点,但依然是建议使用枚举而不是const int来做枚举,那样问题只会更多。
强枚举类型
C++11标准增加了强枚举类型,为了保证老代码的兼容性,同时也兼容了旧的特性,新增的枚举类型具有三个特性:
- 枚举标识符属于强枚举类型的作用域。
- 枚举标识符不会隐式转换为整型。
- 能指定强枚举类型的底层类型,底层类型默认为int类型。
基本上就是让枚举不是一个int的别名,而是一个独立的完全定义,具备完全语义的类型,同时解决了枚举值作用域的问题。
为了兼容旧的逻辑,所以使用了新的标识符,从enum替换成了enum class。
列表初始化有底层类型枚举对象
这一段真的很难理解,为什么C++标准要搞这种东西,即使书里面有一些解释,我还是觉得不太理解…
首先强枚举类型支持由int作为参数的列表初始化:
enum class Color {
Red,
Green,
Blue
};
int main()
{
Color c{5};
Color c1 = 5;
Color c2 = {5};
Color c3(5);
};
这个例子真的震惊到我,Color的范围不是[0~2]吗,怎么就能赋值成5?
而且{5}和(5)的差别是列表初始化构造函数和参数构造函数,为什么要有这种奇怪的特性?C++真的越来越折磨人。。。
说是为了定义一种特殊的整数类型,同时这个整数类型不能跟其他的整数互相转换,强枚举类型符合这个特性,所以通过列表初始化构造函数让强枚举类型变成了一种非通用整数类型的整数类型。
C++真的越来越折磨人。。。
用using打开强枚举类型
可以使用using namesapce;的方式,省略掉强枚举类型的前缀,直接在上下文使用枚举值。
enum class Color {
Red,
Green,
Blue
}
const char* ColorToString(Color c)
{
switch(c)
{
case Color::Red: return"Red";
case Color::Green: return"Green”
case Color::Blue: return"Blue";
default:
return"none";
}
}
可以改成:
enum class Color {
Red,
Green,
Blue
}
const char* ColorToString(Color c)
{
switch(c)
{
using Color;
case Red: return"Red";
case Green: return"Green”
case Blue: return"Blue";
default:
return"none";
}
}
End.