枚举类默认初始化

tan*_*ngy 8 c++ c++11

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

这是一个最小的示例(在线试用

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;
}
Run Code Online (Sandbox Code Playgroud)

在两种情况下我都为零。那么默认初始化是否总是选择第一个枚举类型(例如,此处X = 0)?我知道对于标准枚举它是UB,但是我不确定枚举类的语义吗?我也在CPPReference查询了此信息,但没有找到有关它的任何相关信息-是否也可以获得标准参考?

Jan*_*ans 5

如果具有固定基础类型的枚举位于直接初始化的上下文中,并且初始值设定项列表包含不涉及缩小转换的单个元素,则可以通过初始值设定项列表对其进行初始化。

[dcl.枚举]/8

[...]可以定义一个具有未由任何枚举器定义的值的枚举。

[dcl.init]/6.1

对 T 类型的对象或引用进行零初始化意味着:

(6.1) 如果T是标量类型,则该对象被初始化为通过将整数字面量 0(零)转换为T

也就是说,可以使用不在其枚举数范围内的值来初始化枚举,但当它确实落入范围内时,它就对应于该枚举数。

在您的示例中,零初始化初始化abto0对应于 enumerator X,这意味着......您的示例定义良好。


Igo*_*nik 5

[expr.type.conv] / 1简单型说明符(10.1.7.2)或类型名称说明符(17.6),接着以带括号的可选*表达式列表或通过支撑-INIT列表(初始化)构造一个给定初始值设定项的指定类型的值。

[expr.type.conv]/2 ... 否则,表达式是指定类型的纯右值,其结果对象使用初始化程序直接初始化 (11.6)。


[dcl.init]/(17.4) — 如果初始化器是(),则对象是值初始化的。


[dcl.init] / 8值初始化的类型的对象T是指:

(8.4) — 否则,对象是零初始化的。


[dcl.init]/6对 T 类型的对象或引用进行零初始化意味着:

(6.1) — 如果T是标量类型 (6.9),则对象被初始化为通过将整数文字 0(零)转换为T


[basic.types]/9 ... 枚举类型 ... 统称为标量类型

放在一起,ALPHA()相当于static_cast<ALPHA>(0)