std::array<int, 10>作为类成员会被零初始化吗?

27
struct MyClass
{
  std::array<int, 10> stdArr;

  MyClass() : stdArr()
  {}
};

MyClass c;

问题:

  1. c.stdArr是否进行了零初始化?
  2. 如果是,为什么?

我的自相矛盾的答案:

  1. 它进行了零初始化: std::array希望像c数组一样行事。 如果在上面的示例中stdArr是一个c数组,则在初始化列表中的stdArr()将进行零初始化。我预计在初始化列表中编写member()会初始化对象。

  2. 它没有进行零初始化:

    • std::array通常有一个成员,在我的情况下为int[10] _Elems;
    • 通常不会对基本类型和基本类型的数组(如int[N])进行默认初始化。
    • std::array是聚合类型,这意味着它是默认构造的。
    • 因为没有自定义构造函数来初始化_Elems,所以我认为它没有进行零初始化。

根据C++11标准,std::array的正确行为是什么?


CPP 参考手册 表示,聚合初始化适用于 std::array,即元素零初始化。 - user529758
@H2CO3 事实上,聚合初始化起作用意味着它可以使用{...}语法进行初始化。但这在这里并不相关,因为没有聚合初始化。 - user743382
我链接了另一个问题,其中有完整的解释何时进行默认初始化和何时进行零初始化。 - Jan Hudec
2个回答

21

c.stdArr是否进行了零初始化?

是的。

如果是-为什么?

这执行了stdArr值初始化:

MyClass() : stdArr() {}

在这种情况下,值初始化的效果是对象的零初始化编辑: 什么是聚合体和POD?中有大量相关信息。

4
我本来以为 : stdArr() 只是调用了 std::array 的默认构造函数,它什么也不做的!? - Martin85
4
@Martin85,那不是它的工作方式。一个人必须提供一个不执行任何操作的用户定义默认构造函数(在此过程中使std::array成为非聚合体)。这是C++提供给我们用于零初始化POD和聚合体的处理方法。 - juanchopanza
1
(可怕的)实时示例(绝不是证明,我知道) - gx_
感谢您提供精确的答案和链接。 - Peter
@gx_ 在你的测试中,如果我们查看A1和A2,它们在默认情况下具有非零值。这意味着只有在使用值初始化({})时才会获得零初始化。当您使用默认初始化(即A1和A2)时,您将获得随机垃圾(无初始化),无论是std array还是c array - v.oddou

0
"

“std::array想要表现得像C数组”并不是标准所描述的行为。它是一个用户定义类型,而用户定义类型的成员是通过调用它们的构造函数进行初始化的,即array<int,10>::array()

"

10
std::array没有构造函数。 - R. Martinho Fernandes
@R.MartinhoFernandes,那么它如何与initializer_list一起工作? - sasha.sochka
@sasha.sochka,它不行。http://coliru.stacked-crooked.com/view?id=32781f14670c8ccc79670abf2bca66f5-8dcf59174449f11e872bc3faded12b76。 - R. Martinho Fernandes
1
@MSalters 它在任何情况下都不能被调用。 - R. Martinho Fernandes
1
@sasha.sochka 不,它使用的是聚合初始化,而不是initializer_list。请参见http://coliru.stacked-crooked.com/view?id=0243724bed66c7d8c6d70275ba07a61e-8dcf59174449f11e872bc3faded12b76和http://coliru.stacked-crooked.com/view?id=7fc7cf92253d2f2aead7d08451346bec-8dcf59174449f11e872bc3faded12b76。 - R. Martinho Fernandes
显示剩余10条评论

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