默认初始化 std: : 数组? ?

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

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

编辑 : 在 首选上,缺省构造函数描述说:

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

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

110867 次浏览

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

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

根据定义,默认初始化是在没有指定其他初始化时发生的初始化; C + + 语言保证您没有提供显式初始化器的 任何对象将被默认初始化(C + + 118.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_int和两种数组的所有成员都被初始化为零。

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

Cppreference.com 的描述实际上有点误导。std::array是一个聚合类,如果元素类型是原始的,那么它就是 POD: “普通的旧数据”,其语义与 C 语言非常匹配。std::array< int, N >的隐式定义构造函数是 微不足道构造函数,它完全不做任何事情。

std::array< int, 3 >()std::array< int, 3 > x{}这样提供零值的语法不会通过调用构造函数来实现。得到零是 值初始化的一部分,在 C + + 118.5/8中指定:

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

ーー如果 T 是一个(可能是 cv 限定的)类类型,没有用户提供或删除的缺省构造函数,那么对象是零初始化的... ... ,如果 T 有一个非平凡的缺省构造函数,那么对象是默认初始化的;

std::array没有用户提供的缺省构造函数,所以它得到零初始化。它有一个隐式定义的缺省构造函数,但它是微不足道的,所以它从来没有默认初始化。(但是这没有什么区别,因为根据定义进行的简单初始化在运行时没有任何效果。)

如果没有,是否有一种语法可以在所有数组(包括零大小的数组)上将所有元素初始化为它们的默认值?

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

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

对于某些情况,C + + 11 : array: : fill是一个很好的选择。