为什么 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
,它会添加到矢量并相应地修改它的大小。
最近在学习标准库算法,对函数有疑问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
,它会添加到矢量并相应地修改它的大小。