枚举类默认初始化
Enum Class Default Initialization
枚举类的默认初始化/构造是由行为定义的吗?
这里是一个最小的例子(尝试在线)
enum class ALPHA{
X = 0,
Y = 1,
Z = 2,
};
int main()
{
ALPHA a = ALPHA(); // use default constructor
ALPHA b{}; // use default initialization
std::cout <<static_cast<int>(a) << std::endl; // 0
std::cout <<static_cast<int>(b) << std::endl; // 0
return 0;
}
这两种情况我都是零。那么,默认初始化是否总是选择第一个枚举类型(例如,这里X=0)?我知道它是标准枚举的UB,但我不确定枚举类的语义?我也在CPPReference上查了这个,但没有找到任何相关信息——有可能也得到一个标准的参考吗?
[expr.type.conv]/1一个简单类型说明符(10.1.7.2)或类型名说明符撑的init列表。
[expr.type.conv]/2…否则,表达式是指定类型的prvalue,其结果对象使用初始值设定项直接初始化(11.6)。
[dcl.init]/(17.4)--如果初始值设定项是
()
,则对象被值初始化。
[dcl.init]/8对于值初始化类型为
T
的对象表示:(8.4)--否则,对象初始化为零。
[dcl.init]/6为零初始化T类型的对象或引用意味着:
(6.1)-如果
T
是标量类型(6.9),则将对象初始化为通过将整数文字0(零)转换为T
而获得的值
[基本类型]/9…枚举类型。。。统称为标量类型。
综合起来,ALPHA()
相当于static_cast<ALPHA>(0)
枚举可以由初始值设定项列表初始化,如果它在直接初始化的上下文中,并且初始化项列表包含一个不涉及缩小转换的元素。
[dcl.enum]/8
[…]可以定义其任何枚举器都未定义值的枚举。
[dcl.init]/6.1
为零初始化T类型的对象或引用意味着:
(6.1)如果
T
是标量类型,则将对象初始化为通过将整数文字0(零)转换为T
而获得的值
也就是说,可以用不在枚举器范围内的值初始化枚举,但当它确实在范围内时,它就对应于枚举器。
在您的示例中,零初始化使用对应于枚举器X
的0
将a
和b
初始化为,这意味着。。。你的例子定义得很好。
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 副本初始化的默认模板参数推导
- 使用 std::分配器在 constexpr 中进行默认初始化
- 在C++中使用默认构造函数初始化对象的不同方法
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数时使用垃圾数据初始化对象
- 为什么对象默认初始化,但基元不在C++?
- 默认参数和空列表初始化
- 为什么std::atomic的默认构造函数不默认初始化底层存储值
- C++中未初始化成员布尔变量的默认值是多少?
- 两个成员,在Base中默认初始化,可能在Derived中非默认初始化
- 默认初始化无法正常工作
- 如何用默认值0或-1初始化unordered_set
- C++11 默认类成员初始化与初始值设定项列表同时
- 使用聚合初始化模拟默认函数参数是否存在任何陷阱?
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 在皮条类中初始化默认值的最佳位置
- 值初始化:默认初始化或零初始化