为什么 fill_n() 不能与 vector.reserve() 一起使用?

Why fill_n() does not work with vector.reserve()?

最近在学习标准库算法,对函数有疑问fill_n(iter, n, val)。此函数要求容器至少有 n 个从 iter.

开始的元素

测试代码如下:

// Version 1, Error
vector<int> vec;
vec.reserve(10);  // Only allocate space for at least 10 elements
fill_n(vec.begin(), 10, 0);

// Version 2, OK
vector<int> vec;
vec.resize(10);  // Value initialized 10 elements
fill_n(vec.begin(), 10, 0);

// Version 3, OK
vector<int> vec;
fill_n(back_inserter(vec), 10, 0);  // Push back 10 elements via back_inserter

为什么版本 1 代码错误而版本 2 & 3 没有?

reserve 不初始化任何东西。它只是保留一些 space 所以每次推送新项目时都不会重新分配。 因此,告诉 fill_n 将其结果直接推送到末尾的 vector 的解决方案。

改变这个:

// Version 1, Error
vector<int> vec;
vec.reserve(10);  // Only allocate space for at least 10 elements
fill_n(vec.begin(), 10, 0);

收件人:

// Version 1, Corrected
vector<int> vec;
vec.reserve(10);  // Only allocate space for at least 10 elements
fill_n(std::back_inserter(vec), 10, 0);

reserve只保留space,但向量大小不变。 begin 返回的迭代器不能递增到向量末尾之后,因为它是(不变的)大小决定向量末尾的位置,所以会出现错误。

版本 1 不起作用,因为:

std::reserve 修改矢量的 容量 而不是它的大小。 std::fill_n 要求容器事先具有正确的 大小

版本 2 有效,因为:

std::resize 修改向量的大小而不仅仅是它的容量。

版本 3 有效,因为:

std::back_inserter 将在矢量上调用 push_back,它会添加到矢量并相应地修改它的大小。