Spec-Zone.ru › C++

std::deque

Определено в заголовочном файле <deque>
template<
    class T,
    class Allocator = std::allocator<T>
> class deque;
(1)
namespace pmr {
    template< class T >
    using deque = std::deque<T, std::pmr::polymorphic_allocator<T>>;
}
(2) (начиная с C++17)

std::deque (двусторонняя очередь) — это индексируемый контейнер последовательности, обеспечивающий быструю вставку и удаление как в начале, так и в конце. Кроме того, вставка и удаление с любого конца deque никогда не делают недействительными указатели или ссылки на остальные элементы.

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

Объём памяти deque автоматически увеличивается и уменьшается по мере необходимости. Расширение deque обходится дешевле, чем расширение std::vector, поскольку не требует копирования существующих элементов в новое место в памяти. С другой стороны, deque обычно требует значительного минимального объёма памяти: deque, содержащий всего один элемент, должен выделить весь внутренний массив (например, 8 размеров объекта в 64-разрядной libstdc++; 16 размеров объекта или 4096 байт — в зависимости от того, что больше, — в 64-разрядной libc++).

Сложность (эффективность) распространённых операций над deque:

  • Произвольный доступ — постоянная O(1).
  • Вставка или удаление элементов в конце или начале — постоянная O(1).
  • Вставка или удаление элементов — линейная O(n).

std::deque соответствует требованиям Контейнера, Контейнера с учётом аллокатора, Контейнера последовательности и Обратимого контейнера.

Все функции-члены std::deque являются constexpr: объекты std::deque можно создавать и использовать при вычислении константного выражения.

Однако объявление переменной constexpr std::deque обычно является ошибкой, поскольку при константном вычислении любое динамически выделенное хранилище должно быть освобождено в рамках того же вычисления, чего обычно не происходит с инициализатором std::deque.

(начиная с C++26)

Параметры шаблона

T - Тип элементов.
T должен соответствовать требованиям CopyAssignable и CopyConstructible. (до C++11)
Требования, предъявляемые к элементам, зависят от фактически выполняемых операций над контейнером. Как правило, тип элемента должен быть полным типом и соответствовать требованиям Erasable, однако многие функции-члены накладывают более строгие требования. (начиная с C++11)
Allocator - Аллокатор, используемый для выделения и освобождения памяти, а также для конструирования и уничтожения элементов в этой памяти. Тип должен соответствовать требованиям Allocator. Поведение не определено(до C++20)Программа некорректна(начиная с C++20), если Allocator::value_type не совпадает с T.

Инвалидация итераторов

Операции Что становится недействительным
Все операции только для чтения. Никогда.
swap, std::swap Итератор за последним элементом может стать недействительным (определяется реализацией).
shrink_to_fit, clear, insert,
emplace, push_front, push_back,
emplace_front, emplace_back
Всегда.
erase При удалении в начале — только удалённые элементы.
При удалении в конце — только удалённые элементы и итератор за последним элементом.
В остальных случаях инвалидируются все итераторы.

Не определено, когда итератор за последним элементом становится недействительным.

(до C++11)

Итератор за последним элементом также становится недействительным, если только удалённые
элементы не находятся в начале контейнера и последний
элемент не удаляется.

(начиная с C++11)
resize Если новый размер меньше старого — только удалённые элементы и
итератор за последним элементом.
Если новый размер больше старого — все итераторы становятся недействительными.
В остальных случаях ни один итератор не становится недействительным.

pop_front, pop_back К удалённому элементу.

Итератор за последним элементом может стать недействительным (определяется реализацией).

(до C++11)

Итератор за последним элементом также становится недействительным.

(начиная с C++11)

Примечания об инвалидации

  • При вставке с любого конца deque ссылки не становятся недействительными при выполнении insert и emplace.
  • push_front, push_back, emplace_front и emplace_back не делают недействительными никакие ссылки на элементы deque.
  • При удалении с любого конца deque ссылки на неудалённые элементы не становятся недействительными при выполнении erase, pop_front и pop_back.
  • Вызов resize с меньшим размером не делает недействительными ссылки на неудалённые элементы.
  • Вызов resize с большим размером не делает недействительными ссылки на элементы deque.

Типы-члены

Тип-член Определение
value_type T
allocator_type Allocator
size_type беззнаковый целочисленный тип (обычно std::size_t)
difference_type знаковый целочисленный тип (обычно std::ptrdiff_t)
reference value_type&
const_reference constvalue_type&
pointer

Allocator::pointer

(до C++11)

std::allocator_traits<Allocator>::pointer

(начиная с C++11)
const_pointer

Allocator::const_pointer

(до C++11)

std::allocator_traits<Allocator>::const_pointer

(начиная с C++11)
iterator LegacyRandomAccessIterator и ConstexprIterator(начиная с C++26) к value_type
const_iterator LegacyRandomAccessIterator и ConstexprIterator(начиная с C++26) к constvalue_type
reverse_iterator std::reverse_iterator<iterator>
const_reverse_iterator std::reverse_iterator<const_iterator>

Функции-члены

(constructor)
создаёт deque
(функция-член открытого доступа)
(destructor)
уничтожает deque
(функция-член открытого доступа)
operator=
присваивает контейнеру значения
(функция-член открытого доступа)
assign
присваивает контейнеру значения
(функция-член открытого доступа)
assign_range
(C++23)
присваивает контейнеру диапазон значений
(функция-член открытого доступа)
get_allocator
возвращает связанный аллокатор
(функция-член открытого доступа)
Доступ к элементам
at
предоставляет доступ к указанному элементу с проверкой границ
(функция-член открытого доступа)
operator[]
предоставляет доступ к указанному элементу
(функция-член открытого доступа)
front
предоставляет доступ к первому элементу
(функция-член открытого доступа)
back
предоставляет доступ к последнему элементу
(функция-член открытого доступа)
Итераторы
begincbegin
(C++11)
возвращает итератор на начало
(функция-член открытого доступа)
endcend
(C++11)
возвращает итератор на конец
(функция-член открытого доступа)
rbegincrbegin
(C++11)
возвращает обратный итератор на начало
(функция-член открытого доступа)
rendcrend
(C++11)
возвращает обратный итератор на конец
(функция-член открытого доступа)
Ёмкость
empty
проверяет, пуст ли контейнер
(функция-член открытого доступа)
size
возвращает количество элементов
(функция-член открытого доступа)
max_size
возвращает максимально возможное количество элементов
(функция-член открытого доступа)
shrink_to_fit
(DR*)
уменьшает использование памяти, освобождая неиспользуемую память
(функция-член открытого доступа)
Модификаторы
clear
очищает содержимое
(функция-член открытого доступа)
insert
вставляет элементы
(функция-член открытого доступа)
insert_range
(C++23)
вставляет диапазон элементов
(функция-член открытого доступа)
emplace
(C++11)
создаёт элемент на месте
(функция-член открытого доступа)
erase
удаляет элементы
(функция-член открытого доступа)
push_back
добавляет элемент в конец
(функция-член открытого доступа)
emplace_back
(C++11)
создаёт элемент на месте в конце
(функция-член открытого доступа)
append_range
(C++23)
добавляет диапазон элементов в конец
(функция-член открытого доступа)
pop_back
удаляет последний элемент
(функция-член открытого доступа)
push_front
вставляет элемент в начало
(функция-член открытого доступа)
emplace_front
(C++11)
создаёт элемент на месте в начале
(функция-член открытого доступа)
prepend_range
(C++23)
добавляет диапазон элементов в начало
(функция-член открытого доступа)
pop_front
удаляет первый элемент
(функция-член открытого доступа)
resize
изменяет количество хранящихся элементов
(функция-член открытого доступа)
swap
обменивает содержимое
(функция-член открытого доступа)

Функции, не являющиеся членами

operator==operator!=operator<operator<=operator>operator>=operator<=>
(удалён в C++20)(удалён в C++20)(удалён в C++20)(удалён в C++20)(удалён в C++20)(C++20)
лексикографически сравнивает значения двух dequeов
(шаблон функции)
std::swap(std::deque)
специализирует алгоритм std::swap
(шаблон функции)
erase(std::deque)erase_if(std::deque)
(C++20)
удаляет все элементы, удовлетворяющие заданным критериям
(шаблон функции)

Руководства по выводу типов

(начиная с C++17)

Примечания

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__cpp_lib_containers_ranges 202202L (C++23) Создание контейнеров и вставка в них с использованием диапазонов
__cpp_lib_constexpr_deque 202502L (C++26) Константные выражения std::deque

Пример

#include <deque>
#include <iostream>

int main()
{
    // Create a deque containing integers
    std::deque<int> d = {7, 5, 16, 8};
    
    // Add an integer to the beginning and end of the deque
    d.push_front(13);
    d.push_back(25);
    
    // Iterate and print values of deque
    for (int n : d)
        std::cout << n << ' ';
    std::cout << '\n';
}

Вывод:

13 7 5 16 8 25

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.

DR Применён к Опубликованное поведение Корректное поведение
LWG 230 C++98 Для T не требовалось соответствие требованиям CopyConstructible
(элемент типа T мог оказаться неконструируемым)
Для T также требуется соответствие
требованиям CopyConstructible

См. также

queue
адаптирует контейнер для предоставления очереди (структуры данных FIFO)
(шаблон класса)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/deque

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API