默认初始化std :: array?


103

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

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


不要这样 它是默认声明的,因此基本上与T x[N]语法等效。
拉普兹

Answers:


148

根据定义,默认初始化是未指定其他初始化时发生的初始化。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样式数组和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_old_int和两种数组的所有成员都初始化为零。


如果它是一个类成员怎么办:struct X {std :: array <int,12> X():dozen(){}那会给我十二个零吗?
gerardw 2013年

4
@gerardw根据标准,是的。当心MSVC中的错误,它无法正确实现某些情况下的值初始化。
Casey 2013年

1
实际上boost表示是这样,并通过boost::value_initialized 链接解决该问题,但是我认为VC12(VS2013)现在有更好的支持。
v.oddou 2015年

1
让我希望委员会应要求将标准更改为默认值初始化和破坏值。即std :: array <int,12> = {std :: unetermined}; 或什么
Viktor Sehr

在实践中,将某事物初始化为不确定的值甚至意味着什么?有什么选择?
安德鲁

21

默认初始化是标准中的一个术语,可能意味着根本不进行初始化,因此您可能是指零初始化

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 >)不能为零。


6

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

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


0

首先,尽管标量类型T的默认初始化实际上不执行任何操作,但是T x [N]会默认初始化元素。上面的内容也适用于std :: array x。我认为您需要的是列表初始化。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.