新分配的 std::vector<int> 元素是不是初始化为 0?

Posted

技术标签:

【中文标题】新分配的 std::vector<int> 元素是不是初始化为 0?【英文标题】:Are newly allocated elements of std::vector<int> initialized to 0?新分配的 std::vector<int> 元素是否初始化为 0? 【发布时间】:2013-02-15 13:06:24 【问题描述】:

假设我们使用std::vector&lt;int&gt;std::vector&lt;long&gt;。随着向量大小的增长,新分配的元素是默认初始化为0,还是程序员需要显式地将它们初始化为0?

【问题讨论】:

【参考方案1】:

新的元素是值初始化的:

[C++11: 23.3.6.3/9]:void resize(size_type sz); 效果:如果sz &lt;= size(),则相当于erase(begin() + sz, end());。如果是size() &lt; sz,则将sz - size() value-initialized 元素附加到序列中。

对于intlong 这意味着0

[C++11: 8.5/7]: T类型的对象进行值初始化意味着

如果T 是具有用户提供的构造函数 (12.1) 的(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(并且如果T 没有可访问的默认构造函数); 如果 T 是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,则对象为零初始化,并且如果 T 的隐式声明的默认构造函数是非微不足道,调用该构造函数。 如果T是数组类型,那么每个元素都是值初始化的; 否则,对象被零初始化。

值初始化的对象被认为是已构造的,因此受本国际标准适用于“构造的”对象、“构造函数已完成的对象”等的规定的约束,即使没有调用构造函数用于对象的初始化。

但请注意,这不是在谈论向量末尾的“保留”空间。该空间不包含任何有效元素,零-初始化或其他方式。此答案和标准措辞仅涉及您在执行 resize 时获得的元素,而没有为新元素指定显式值。

【讨论】:

【参考方案2】:

根据 C++11 标准的第 23.3.6.3/9 段(关于 std::vector::resize()):

void resize(size_type sz);

效果:如果sz value-initialized 元素附加到序列中。

此外,根据标准第 8.5/7 段:

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

——如果 T 是一个(可能是 cv 限定的)类类型(第 9 条),带有一个用户提供的构造函数(12.1),那么 调用 T 的默认构造函数(如果 T 没有可访问的默认值,则初始化格式错误 构造函数);

——如果 T 是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,那么对象 是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则该构造函数是 调用。

——如果T是一个数组类型,那么每个元素都是值初始化的;

否则,对象被零初始化

这意味着在 int 的情况下,新创建的元素的值初始化为 0

【讨论】:

【参考方案3】:

是的,当std::vector 改变大小时(可能通过std::vector::resize),任何新元素都将被值初始化。对于 intlong 这样的类型,值初始化会导致零初始化,顾名思义,会将值设置为 0。

【讨论】:

以上是关于新分配的 std::vector<int> 元素是不是初始化为 0?的主要内容,如果未能解决你的问题,请参考以下文章

模板typedef与std :: vector有自定义分配器

是否可以在一行中初始化新的 std::vector ?

C++ 向量分配器错误

向量的分配向量

使用 std::vector 的开销?

具有可访问构造函数的 std::vector< T >::iterator