std :: array的默认初始化?

时间:2013-08-18 03:07:52

标签: c++11 initialization default-constructor stdarray

使用C ++ 11 std::array,我是否可以保证语法std::array<T, N> x;将默认初始化数组的所有元素?

编辑:如果没有,是否有一种语法适用于所有数组(包括零大小的数组)以将所有元素初始化为其默认值?

编辑:在cppreference上,默认构造函数说明为:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

所以答案可能是肯定的。但我想根据标准或未来标准确定这一点。

5 个答案:

答案 0 :(得分:120)

根据定义,默认初始化是在未指定其他初始化时发生的初始化; C ++语言保证您未提供显式初始化程序的任何对象将被默认初始化(C ++11§8.5/ 11)。其中包括std::array<T, N>T[N]类型的对象。

请注意,默认初始化无效的类型会使对象的值不确定:任何非类非数组类型(第8.5 / 6节)。因此,具有此类型的默认初始化对象数组将具有不确定的值,例如:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

c样式数组和std::array都填充了不确定值的整数,就像plain_int具有不确定的值一样。

  

是否有一种语法适用于所有数组(包括零大小的数组)以将所有元素初始化为其默认值?

我猜测当你说“达到他们的默认值”时,你的意思是“将所有元素初始化为T{}”。那不是默认初始化,它是值初始化(8.5 / 7)。通过为每个声明提供一个空的初始值设定项,您可以在C ++ 11中轻松地请求值初始化:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

将依次初始化所有数组元素,导致plain_old_int,以及两种数组的所有成员,初始化为零。

答案 1 :(得分:17)

默认初始化是标准中的一个术语,可能意味着根本没有初始化,所以你可能意味着零初始化

cppreference.com上的描述实际上有点误导。 std::array是一个聚合类,如果元素类型是原始的,则它是POD:“普通旧数据”,其语义与C语言紧密匹配。隐式定义的std::array< int, N >构造函数是一个琐碎的构造函数,它完全没有任何作用。

提供归零值的std::array< int, 3 >()std::array< int, 3 > x{}等语法不会通过调用构造函数来实现。获取零是 value-initialization 的一部分,在C ++11§8.5/ 8中指定:

  

对T类型的对象进行值初始化意味着:

     

- 如果T是(可能是cv限定的)类类型而没有用户提供或删除的默认构造函数,则该对象为零初始化...,如果T具有非平凡的默认构造函数,则该对象为默认值-initialized;

std::array没有用户提供的默认构造函数,因此它被初始化为零。它有一个隐式定义的默认构造函数,但它很简单,因此它永远不会默认初始化。 (但这并没有什么区别,因为根据定义的简单初始化在运行时没有效果。)

  

如果没有,是否有一种语法适用于所有数组(包括零大小的数组)以将所有元素初始化为其默认值?

C风格的数组和std::array都是聚合,完全对任何聚合进行零初始化的方法是使用语法= {}。这适用于C ++ 98。请注意,C样式数组的范围不能为零,sizeof (std::array< X, 0 >)不为零。

答案 2 :(得分:6)

T x[N];std::array<T, N> x;都默认初始化数组的每个元素。

例如,如果T = std::string,则每个元素都是空字符串。如果T是没有默认构造函数的类,则两者都将无法编译。如果T = int,则每个元素都将具有不确定的值(除非该声明恰好位于命名空间范围内)

答案 3 :(得分:0)

首先,T x [N]默认初始化元素,尽管标量类型T的默认初始化实际上什么都不做。以上也适用于std :: array x。我认为你需要的是列表初始化。

答案 4 :(得分:0)

在某些情况下,

C ++ 11 std::array::fill是一个不错的选择。