std::vector::insert 是否根据定义保留

Does std::vector::insert reserve by definition?

本文关键字:定义 保留 是否 vector insert std      更新时间:2023-10-16

std::vector上调用insert成员函数时,它会在"推回"新项目之前reserve吗?我的意思是标准是否保证这一点?

换句话说,我应该这样做吗:

std::vector<int> a{1,2,3,4,5};
std::vector<int> b{6,7,8,9,10};
a.insert(a.end(),b.begin(),b.end());

或者像这样:

std::vector<int> a{1,2,3,4,5};
std::vector<int> b{6,7,8,9,10};
a.reserve(a.size()+b.size());
a.insert(a.end(),b.begin(),b.end());

还是另一种更好的方法?

关于函数的复杂性 [link]:

插入元素数量的线性(复制/移动构造( 加上位置(移动(后的元素数。

此外,如果范围插入 (3( 中的输入迭代器至少不是 前向迭代器类别(即,只是一个输入迭代器(的新 无法事先确定容量,并且插入会产生 大小(重新分配(的额外对数复杂性。

因此,有两种情况:

  • 可以确定新容量,因此您无需调用储备
  • 无法确定新容量,因此调用reserve应该很有用。

根据定义,std::vector::insert保留吗?

并非总是如此;取决于当前的容量。

来自草案 N4567, §23.3.6.5/1 ([vector.modifiers](:

如果新大小大于旧容量,则会导致重新分配。

如果vector中分配的内存容量足够大以包含新元素,则不需要为vector进行额外分配。所以不,那么它不会保留内存。

如果vector容量不够大,则分配一个新块,移动/复制当前内容并插入新元素。未指定确切的分配算法,但通常与reserve()方法中使用的算法相同。

。还是另一种更好的方法?

如果您担心在将元素插入vector时分配过多,则使用要添加的预期元素数的大小调用 reserve 方法确实会最大限度地减少分配。

vector是否在插入/任何插入之前调用reserve? 即,它是否在单个分配中分配了足够的容量?

没有保证。它如何知道输入迭代器之间的距离?鉴于insert方法可以采用输入迭代器(即单遍迭代器(,它无法计算预期的大小。该方法是否可以计算出迭代器在其他地方(例如指针或随机访问迭代器(的大小?是的,可以。会吗?取决于实施和所做的优化。

从文档中可以看出:

如果新 size(( 大于旧容量 ((,则会导致重新分配。

另请注意,在这种情况下,所有迭代器和引用都将失效。

因此,不言而喻,重新分配负责insert,如果您一次查看这些操作,则就像在每一步都进行了一致的储备大小加一操作。
您可以争辩说,在发生多个重新分配的情况下,插入顶部的reserve调用会加快所有速度......嗯,对,它可以提供帮助,但这主要取决于您的实际问题。