Подтвердить что ты не робот

Почему в С++ std::vector нет метода pop_front?

Почему в С++ std::vector нет метода pop_front?

4b9b3361

Ответ 1

Поскольку std::vector не имеет особой функции в отношении вставки элементов спереди, в отличие от некоторых других контейнеров. Функциональность, предоставляемая каждым контейнером, имеет смысл для этого контейнера.

Вероятно, вы должны использовать std::deque, который явно хорош для вставки спереди и сзади.

Отметьте эту диаграмму вне.

Ответ 2

вектор обычно реализуется примерно так:

struct 
{
  T* begin; // points to the first T in the vector
  T* end; // points just after the last T in the vector
  int capacity; // how many Ts of memory were allocated
};

"begin" служит двойным делом как "указатель на первый T в векторе" и "указатель на всю выделенную память". поэтому невозможно "вытащить" элементы с передней части вектора, просто увеличивая "начало" - сделайте это, и у вас больше нет указателя на память, которую вы должны освободить. что приведет к утечке памяти. поэтому "pop_front" нужно будет скопировать все Ts с обратной стороны вектора на фронт вектора, и это сравнительно медленно. поэтому они решили оставить его вне стандарта.

что вы хотите, это примерно так:

struct 
{
  T* allocated; // points to all the memory we allocated
  T* begin; // points to the first T in the vector
  T* end; // points just after the last T in the vector
  int capacity; // how many Ts of memory were allocated
};

с этим вы можете "pop_front", перемещая "начало" вперед и назад, без опасности забыть, какую память освободить позже. почему std::vector не работает так? я думаю, что это был вопрос вкуса среди тех, кто написал стандарт. их целью было, вероятно, предоставить простейший "динамически изменяемый массив", который они могли бы, и я думаю, что они преуспели.

Ответ 3

Simple. Просто попробуйте:

vec.erase(vec.begin());

Ответ 4

Потому что push_back и pop_back являются специальными операциями для вектора, для которого требуется только вычисление O(1). Любой другой push или pop занимает O(n).

Это не "ошибка" или "причуда", это просто свойство векторного контейнера. Если вам нужен быстрый pop_front, перейдите в другой контейнер.

Ответ 5

Возможно, потому, что это было бы монументально медленным для больших векторов.

pop_front() для вектора, содержащего 1000 объектов, потребуется 999 operator=() вызовов.

Ответ 6

Однако, если вам нужен pop_front и , не заботьтесь об индексе элементов в векторе, вы можете сделать вид pop_front с чем-то вроде

template<typename T>
void pop_front(std::vector<T>& vec)
{
   vec.front() = vec.back();
   vec.pop_back();
}

Дэн Хиггинс говорит об этом тоже: https://youtu.be/oBbGC-sUYVA?t=2m52s