Вставка вектора C++ & нажимает назад разницу
Я хочу знать, в чем разница(ы) между vector
' s push_back
и insert
функции.
есть ли структурные различия?
есть ли действительно большая разница в производительности?
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())
(возможно, с немного лучшей производительностью), есть несколько важных вещей, чтобы знать об этих функциях:
push_back
существует только наBackInsertionSequence
контейнеры - так, например, он не существует оset
. Он не мог, потому чтоpush_back()
предоставляет вам, что он всегда будет добавлять в конце.- некоторые контейнеры также могут удовлетворить
FrontInsertionSequence
и ониpush_front
. Это удовлетворяетсяdeque
, но не наvector
.- 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
в исходном порядке, и это не несет риска недействительности итератора.