Изменяет ли std::vector.pop_back() емкость вектора?

Если я выделил std::vector для определенного размера и емкости, используя resize() и reserve() в начале моей программы, возможно ли, что pop_back() может «сломать» зарезервированную емкость и вызвать перераспределение?


person jackhab    schedule 08.10.2009    source источник


Ответы (6)


Нет. Единственный способ уменьшить емкость вектора — это трюк со свопингом.

template< typename T, class Allocator >
void shrink_capacity(std::vector<T,Allocator>& v)
{
   std::vector<T,Allocator>(v.begin(),v.end()).swap(v);
}

и даже это не гарантирует работу в соответствии со стандартом. (Хотя трудно представить реализацию, в которой это не работало бы.)

Насколько я знаю, следующая версия стандарта C++ (то, что раньше было C++0x, а теперь стало C++1x) будет иметь std::vector<>::shrink_to_fit().

person sbi    schedule 08.10.2009
comment
Я бы очень не советовал использовать этот трюк по трем причинам: 1. Функция не обязательно делает то, что заявлено. 2 Нарушает принцип наименьшего удивления 3. Потенциально влечет за собой огромные накладные расходы, не говоря уже о потенциальных побочных эффектах копирования вместо перемещения. - person einpoklum; 10.02.2018
comment
@einpoklum: Да, это без движения, и поэтому сегодня неоптимально. Но этому ответу почти десять лет, так что... - person sbi; 10.02.2018
comment
@sbi: тогда я бы тоже не советовал :-( - person einpoklum; 10.02.2018
comment
@einpoklum: Так ты бы хотел, да? Что ж, в то время сообщество C++ думало иначе. Так что разберись. - person sbi; 11.02.2018

Нет. pop_back() не уменьшит емкость вектора. вместо этого используйте std::vector<T>(v).swap(v).

person aJ.    schedule 08.10.2009
comment
Дубликат ответа @sbi; и см. мой комментарий там о трюке подкачки. - person einpoklum; 10.02.2018

В С++ 11 можно вызвать метод shrink_to_fit(), чтобы запросить вектор (а также двухстороннюю очередь или строку), чтобы уменьшить зарезервированное пространство до емкости вектора. Однако обратите внимание, что это зависит от реализации: это просто запрос, и нет никаких гарантий. Вы можете попробовать следующий код:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> myVector;

    for (auto i=1;i!=1e3;++i)
        myVector.push_back(i);

    cout << "Capacity: " << myVector.capacity() << endl;
    myVector.reserve(2000);
    cout << "Capacity (after reserving 2000): " << myVector.capacity() << endl;
    myVector.shrink_to_fit();
    cout << "Capacity (after shrink_to_fit): " << myVector.capacity(); 

}
person Alexandre Cartaxo    schedule 26.11.2015

pop_XXX никогда не изменит емкость. push_XXX может изменить емкость, если вы попытаетесь отправить больше материала, чем позволяет емкость.

person Zanson    schedule 09.10.2009

НЕТ. Как и push_back , pop_back не повлияет на capacity(). Они просто влияют на size().

РЕДАКТИРОВАТЬ:

Я должен был сказать, что push_back не изменит емкость, когда v.size() < v.capacity().

person pierrotlefou    schedule 08.10.2009

Вот код std::vector::pop_back()

void pop_back()
{   // erase element at end
   if (!empty())
   {    // erase last element
      _Dest_val(this->_Alval, this->_Mylast - 1);
      --this->_Mylast;
   }
}

Функция вызывает только деструктор и уменьшает указатель на последний элемент. Код из ВК (Релиз). Так что это не влияет на емкость (или перераспределение) вектора.

person Vladimir Ivanov    schedule 13.04.2013
comment
Одной конкретной реализации недостаточно информации, чтобы определить, что требует стандарт. И это может быть не та реализация, которую использует человек, задающий вопрос. - person Adrian McCarthy; 20.05.2014