Мне было интересно, как реализован pop_back (), чтобы он имел постоянную сложность? Он должен уменьшить размер на 1 и удалить последний элемент.
Точно. Это все, что нужно сделать. Неважно, сколько элементов у вас есть.
Это определение постоянной сложности.
Теперь я где-то видел, что он в основном уменьшает размер на 1 и уничтожает последний элемент через некоторые итератор / указатель
Это верно. Память все еще распределена, но живущий там объект подвергается логическому разрушению.
, но тогда почему мы не можем реализовать pop_front () таким же образом и просто перенаправить наш указатель на первый элемент на следующий ?
Можно! Вот как работает std::deque
, поэтому std::deque
имеет pop_front()
с постоянной сложностью.
Однако вы не можете сделать это, поддерживая другие дешевые операции, потому что это обязательно вызывает фрагментацию памяти после несколько раз. Память распределяется по частям, а векторы должны быть распределены по смежным частям. Представьте, что векторы просто «игнорировали» первый элемент, если вы pop_front()
сделали это - теперь сделайте это пятьсот раз. У вас неиспользованная память, просто сидящая там вечно. Фигово! А что, если вы хотите добавить на фронт сейчас? В конце концов, если вы не захотите использовать бесконечную память, вам придется разделить вашу память на отдельные куски, но это нарушит гарантированную непрерывность.
Другие контейнеры предназначены для того, чтобы дать вам то, что вы хотите, но с компромиссами. В частности, std::deque
не может гарантировать непрерывное хранение. Вот как это предотвращает постоянную загрузку неиспользуемой памяти.