124

使用 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 

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

4

5 回答 5

184

根据定义,默认初始化是在没有指定其他初始化时发生的初始化;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{}”。那不是default-initialization,而是value-initialization (8.5/7)。您可以在 C++11 中通过为每个声明提供一个空的初始值设定项来轻松请求值初始化:

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

这将依次对所有数组元素进行值初始化,从而导致plain_int和两种数组的所有成员都被初始化为零。

于 2013-08-18T04:59:17.307 回答
30

Default-initialization是标准中的一个术语,可能意味着根本没有初始化,所以你可能指的是zero-initialization

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

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

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

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

std::array没有用户提供的默认构造函数,因此它被零初始化。它有一个隐式定义的默认构造函数,但它是微不足道的,所以它永远不会被默认初始化。(但这并没有什么区别,因为根据定义进行的微不足道的初始化在运行时没有影响。)

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

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

于 2013-08-19T00:18:54.717 回答
11

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

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

于 2013-08-18T03:52:45.197 回答
3

C++11 std::array::fill在某些情况下是一个不错的选择。

于 2020-09-11T19:20:58.500 回答
0

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

于 2014-06-26T09:35:08.983 回答