【问题标题】:Zero-initialization of POD typesPOD 类型的零初始化
【发布时间】:2014-09-12 08:44:52
【问题描述】:
struct Foo
{
    char name[10];
    int  i;
    double d;
};

我知道我可以使用以下方法对此类 POD 类型的所有成员进行零初始化:

Foo foo = {0};

我可以进一步简化为:

Foo foo = {};

喜欢原生数组? (int arr[10] = {};)


我不是在用{0} 初始化时询问,除了第一个成员之外的成员是否会被零初始化。我知道这个问题的答案是肯定的。我在问第一个0 是否可以在语法上省略。

我在这个主题上找到的大多数教程都建议使用{0},没有使用{},例如this guide,它被解释为这是因为聚合初始化规则是递归的; ,这比解释更令人困惑。

【问题讨论】:

  • @JoachimPileborg:这非常具有误导性。 int n; 是“像默认构造”,但不设置为零。而是“{} 就像对数据进行值初始化”。

标签: c++ initialization


【解决方案1】:

正如所写,这是聚合初始化。适用的规则是(§8.5.1 [dcl.init.aggr]/p7):

如果列表中的 initializer-clauses 少于 聚合中的成员,然后每个成员未显式初始化 应从其 brace-or-equal-initializer 进行初始化,或者,如果 没有 brace-or-equal-initializer,来自一个空的初始值设定项 列表 (8.5.4)。

§8.5.4 [dcl.init.list]/p3 的相关部分是:

定义了T 类型的对象或引用的列表初始化 如下:

  • 如果T 是聚合,则执行聚合初始化 (8.5.1)。
  • 否则,如果初始值设定项列表没有元素并且T 是具有默认构造函数的类类型,则对象为 值初始化。
  • [省略不相关的项目]
  • 否则,如果初始化列表中没有元素,则对象被值初始化。

简而言之,子聚合是从一个空的初始化列表递归聚合初始化的。其他一切都是值初始化的。所以最终结果是一切都被值初始化,一切都是POD,值初始化意味着零初始化。


如果 T 是 POD 但不是聚合,则聚合初始化不适用,因此您点击了 §8.5.4 [dcl.init.list]/p3 中的第二个要点,这会导致值初始化取而代之的是整个对象。 POD 类必须有一个普通的(因此不是用户提供的)默认构造函数,因此它们的值初始化也意味着零初始化。

【讨论】:

    猜你喜欢
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    相关资源
    最近更新 更多