枚举类默认初始化

时间:2018-12-22 17:44:29

标签: c++ c++11

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

这是一个最小的示例(Try Online

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上进行了查询,但是没有找到任何相关信息-是否也可以获得标准参考?

2 个答案:

答案 0 :(得分:1)

具有固定基础类型的

枚举可以通过 initializer-list 初始化,前提是直接初始化且 initializer-list 包含单个元素且不缩小转换参与其中。

[dcl.enum]/8

  

[...] 可以定义一个其枚举数未定义的枚举。

[dcl.init]/6.1

  

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

     

(6.1)如果T是标量类型,则将该对象初始化为通过将整数常量0(零)转换为T而获得的值

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

在您的示例中,零初始化将ab初始化为0,它们与枚举器X相对应,这意味着...您的示例已得到很好的定义。

答案 1 :(得分:1)

  

[expr.type.conv] / 1 一个简单类型说明符(10.1.7.2)或类型名称说明符(17.6 ),然后加上括号后的可选* expression-list或 braced-init-list (初始值设定项),可在给定初始值设定项的情况下构造指定类型的值。

     

[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

获得的值

  

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

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