C++中的全局强类型枚举默认初始化为什么?

10

我正在尝试确定全局强类型枚举的默认值。 当然,以下代码无法编译。

#include <iostream>
using namespace std;

enum class A{a=10, b=20};

// Global strongly-typed enum, uninitialized
A k;

int main() {
    if(k==A::a)
        cout<<"Equal to a"<<endl;
    else if(k==A::b)
        cout<<"Equal to b"<<endl;
    else if(k==0)
        cout<<"Equal to zero"<<endl;

    return 0;
}

'k'被初始化为什么值?


2
@JohnnyMopp 不,这不是重复的。你链接的那个问题是关于函数作用域未经作用域限定的枚举。而这个问题是关于命名空间作用域经过作用域限定的枚举。两者非常不同。 - Angew is no longer proud of SO
这是一个重复问题。您可以在上面链接的重复答案中找到您的问题的答案。 - glezmen
2
@glezmen 我仍然不这么认为 - 那个问题并没有涵盖作用域枚举。是的,答案是相同的,但这并不意味着它是一个重复的问题。 - Angew is no longer proud of SO
@Angew 如果您在命名空间范围内定义了变量,它将被初始化为0的值。https://dev59.com/c2w15IYBdhLWcg3wFHtZ - glezmen
@glezmen “作用域枚举”是enum class,而“非作用域枚举”只是enum。链接的问题根本没有涉及作用域枚举(enum class类型)。 - Angew is no longer proud of SO
2个回答

10

k具有静态存储期,静态对象在被初始化之前将被零初始化,我们可以通过查看C++标准草案3.6.2非局部变量的初始化2段来了解:

具有静态存储期(3.7.1)或线程存储期(3.7.2)的变量在进行任何其他初始化之前都必须进行零初始化(8.5)。[...]

对于标量类型,这意味着初始化为零,这在第8.5节第6段中得到了说明:

将T类型的对象或引用进行零初始化的意思是:

其中包括以下要点:

如果T是标量类型(3.9),则该对象被初始化为将整型字面值0(零)转换为T所获得的值;105

我们知道从第3.9类型的第9段可知,枚举类型是标量类型:

算术类型(3.9.1)、枚举类型、指针类型、指向成员的指针类型(3.9.2)、std::nullptr_- t以及这些类型的cv限定版本(3.9.3)统称为标量类型。[...]

是一个有效值,因为底层类型可以包含它的值,并且第7.2枚举声明的第8段说枚举可以取一个不由其枚举器定义的值:

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


3

它被初始化为零。请注意,此枚举的基础类型为int(默认情况下),0是一个有效的枚举器,尽管它在枚举的任何枚举器定义中都没有明确使用。

你只需要写

else if( k == static_cast<A>( 0 ) )
    cout<<"Equal to zero"<<endl;

如果您使用C#,那么零可以隐式转换为任何类型的枚举。 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接