Почему в С++ std::vector
нет метода pop_front
?
Почему в С++ std::vector нет метода pop_front?
Ответ 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