C ++ vector的插入& push_back差异

时间:2012-11-10 17:39:58

标签: c++

我想知道vector的{​​{1}}和push_back函数之间有什么区别。

是否存在结构差异?

是否存在非常大的性能差异?

3 个答案:

答案 0 :(得分:79)

最大的不同是他们的功能。 push_back始终在vector的末尾放置一个新元素,insert允许您选择新元素的位置。这会影响性能。 vector元素只有在需要增加它的长度时才会在内存中移动,因为为它分配的内存太少。另一方面,insert强制在新元素的选定位置之后移动所有元素。你只需要为它做一个位置。这就是insert通常效率低于push_back的原因。

答案 1 :(得分:28)

这些功能有不同的用途。 vector::insert允许您在vector的指定位置插入对象,而vector::push_back只会将对象粘贴在最后。请参阅以下示例:

using namespace std;
vector<int> v = {1, 3, 4};
v.insert(next(begin(v)), 2);
v.push_back(5);
// v now contains {1, 2, 3, 4, 5}

您可以使用insertpush_back v.insert(v.end(), value)执行相同的工作。

答案 2 :(得分:6)

除此之外,push_back(x)insert(x, end())的作用相同(可能性能稍好一些),关于这些功能有几个重要的事项要知道:

  1. push_back仅存在于BackInsertionSequence个容器中 - 例如,它set上不存在。它不可能因为push_back()授予你它最终总是会添加。
  2. 某些容器也可以满足FrontInsertionSequence,并且push_front。这由deque满足,但不是vector
  3. insert(x, ITERATOR)来自InsertionSequence,这在setvector中很常见。这样,您可以使用setvector作为多次插入的目标。但是,set还有insert(x),它实际上完全相同(set中的第一个插入只意味着通过从不同的迭代器开始来加速搜索适当的位置 - 在这种情况下使用)。
  4. 注意最后一种情况,如果你要在循环中添加元素,那么执行container.push_back(x)container.insert(x, container.end())将有效地做同样的事情。但是,如果先获得此container.end()然后在整个循环中使用它,则不会出现这种情况。

    例如,您可以冒险以下代码:

    copy(a.begin(), a.end(), inserter(v, v.end());
    

    这样可以有效地将整个a复制到v向量中,以相反的顺序复制,并且只有在您足够幸运且无法为扩展程序重新分配向量时(您可以通过先调用reserve()来防止此问题;如果你没那么幸运,你会得到所谓的UndefinedBehavior(tm)。从理论上讲,这是不允许的,因为每次添加新元素时都会将vector的迭代器视为无效。

    如果你这样做:

    copy(a.begin(), a.end(), back_inserter(v);
    

    它会在原始订单的a末尾复制v,这不会带来迭代器失效的风险。