C++17 非静态 POD 类成员是否用大括号 {} 初始化并设置为 0?

问题描述 投票:0回答:1

收到代码审查评论,指出我的非静态类 POD 成员被设置为无效值。我同意初始值应该是无效的。对于我的情况,0 无效。这是一个例子:

class A
{
  int a_{};  // Is a_ initialized to 0?
  double b_{}; // Is b_ initialized to 0.0?
  // etc.
};

有时我添加了 {} 来处理编译器警告这些类成员应该被初始化。我以为它们会被初始化为零。 (经验观察表明它们是 0,但我正在以某种方式寻找权威来源。)

我查看了这两个链接,但无法确定 {} 结果为 0。
C++11 中默认初始化的含义发生了变化?
C++ 中 POD 类型的默认值和值初始化

清晰简单的来源会很有用。我尝试在这里找到一些东西,但没有运气。
https://eel.is/c++draft/

c++11 c++17 language-lawyer ctor-initializer value-initialization
1个回答
0
投票

假设实际使用了默认成员初始值设定项

{}
,即使用的构造函数没有为给定成员指定任何其他初始值设定项,或者,如果这是一个聚合类,则聚合初始化不会为该成员指定任何其他初始值设定项,那么这些成员的初始化将与它们的声明出现在其他上下文中完全相同,例如作为块作用域变量。

因此请考虑类型

{}
/
int
double
初始化器。初始化行为在从 [dcl.init.general]/16 开始的长决策规则链中指定。第一个适用的规则是 (16.1),因为
{}
braced-init-list 并且所有带大括号的初始化都会根据 [dcl.init.list]/3 导致 list-initialization

在这个新决策链中应用的第一项是(3.11),它声明该对象是值初始化的(因为初始化列表为空)。

值初始化[dcl.init.general]/9中定义,在此决策链中,最后一项(9.3)是第一个应用的,因为

int
double
都不是类或数组类型,并且它声明该对象是零初始化

零初始化是通过另一个决策链在[dcl.init.general]/6中定义的,并且(6.1)已经适用,因为

int
double
是标量类型。它指出该对象的初始化就像通过将整数文字
0
转换为其类型一样。

此时,我希望很清楚

int
成员的值将是
0
double
成员的值将是
0.0
,而无需执行 [conv] 中的隐式转换规则。

© www.soinside.com 2019 - 2024. All rights reserved.