Вставка вектора C++ & нажимает назад разницу


Я хочу знать, в чем разница(ы) между vector ' s push_back и insert функции.

есть ли структурные различия?

есть ли действительно большая разница в производительности?

3 61
c++

3 ответа:

самая большая разница заключается в их функциональности. push_back всегда помещает новый элемент в конце vector и insert позволяет выбрать позицию нового элемента. Это влияет на производительность. vector элементы перемещаются в памяти только тогда, когда необходимо увеличить его длину, потому что слишком мало памяти было выделено для него. С другой стороны insert заставляет переместить все элементы после выбранного положения нового элемента. Вы просто должны сделать место для него. Вот почему insert часто может быть менее эффективным, чем push_back.

функции имеют различные цели. 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}

можно использовать insert для выполнения той же работы, что и push_back С v.insert(v.end(), value).

кроме того, что push_back(x) тут же insert(x, end()) (возможно, с немного лучшей производительностью), есть несколько важных вещей, чтобы знать об этих функциях:

  1. push_back существует только на BackInsertionSequence контейнеры - так, например, он не существует о set. Он не мог, потому что push_back() предоставляет вам, что он всегда будет добавлять в конце.
  2. некоторые контейнеры также могут удовлетворить FrontInsertionSequence и они push_front. Это удовлетворяется deque, но не на vector.
  3. The insert(x, ITERATOR) С InsertionSequence, который является общим для set и vector. Таким образом, вы можете использовать либо set или vector как цель для нескольких вставок. Однако,set дополнительно insert(x), что делает практически то же самое (это первая вставка в set означает только ускорить поиск подходящего места, начиная с другого итератора-функция, не используемая в этом случае).

обратите внимание на последний случай, что если вы собираетесь добавить элементы в цикл, то делаем 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). Теоретически это не допускается, потому что итераторы вектора считаются недействительными каждый раз, когда добавляется новый элемент.

если вы сделаете это таким образом:

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

он будет копировать a в конце v в исходном порядке, и это не несет риска недействительности итератора.