枚举类默认初始化

Enum Class Default Initialization

本文关键字:初始化 默认 枚举      更新时间:2023-10-16

枚举类的默认初始化/构造是由行为定义的吗?

这里是一个最小的例子(尝试在线)

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而获得的值

也就是说,可以用不在枚举器范围内的值初始化枚举,但当它确实在范围内时,它就对应于枚举器。

在您的示例中,零初始化使用对应于枚举器X0ab初始化为,这意味着。。。你的例子定义得很好。