std::inplace_vector
Определён в заголовочном файле <inplace_vector> | ||
|---|---|---|
template<
class T,
std::size_t N
> struct inplace_vector;
| (начиная с C++26) |
std::inplace_vector — это динамически изменяемый массив с непрерывным хранилищем внутри объекта. Элементы типа T хранятся непосредственно в самом объекте и имеют надлежащее выравнивание. Ёмкость внутреннего хранилища фиксируется во время компиляции и равна N.
Элементы хранятся непрерывно, то есть к ним можно обращаться не только через итераторы или оператор произвольного доступа operator[], но и с помощью смещений относительно обычных указателей на элементы. Указатель на элемент inplace_vector можно передать любой функции, которая ожидает указатель на элемент C-массива.
std::inplace_vector соответствует требованиям Container, ReversibleContainer, ContiguousContainer и SequenceContainer, включая большинство необязательных требований к контейнерам последовательностей, за исключением того, что функции-члены push_front, emplace_front, pop_front и prepend_range не предоставляются.
Для любого N, std::inplace_vector<T, N>::iterator и std::inplace_vector<T, N>::const_iterator соответствуют требованиям ConstexprIterator.
Специализация std::inplace_vector<T,0> является TriviallyCopyable и пустой. std::is_trivially_default_constructible_v<std::inplace_vector<T, 0>> также является true.
Любая функция-член std::inplace_vector<T,N>, которая привела бы к вставке сверх ёмкости N, выбрасывает исключение std::bad_alloc.
Сложность основных операций над inplace_vector следующая:
- Произвольный доступ к элементу через
operator[]илиat()— постоянная: 𝓞(1). - Вставка или удаление одного элемента в конце — постоянная: 𝓞(1).
- Вставка или удаление элементов в конце — линейная относительно количества вставленных или удалённых элементов: 𝓞(n).
- Вставка или удаление элементов в начале или середине — линейная относительно количества вставленных или удалённых элементов плюс расстояния до конца вектора: 𝓞(n).
Инвалидация итераторов
Гарантии инвалидации итераторов для std::inplace_vector отличаются от std::vector:
- перемещение
inplace_vectorинвалидирует все итераторы; - обмен двух
inplace_vectorинвалидирует все итераторы (во время обмена итератор продолжает указывать на тот же элемент массива, поэтому его значение может измениться).
Следующие функции-члены могут инвалидировать итераторы: operator=, assign, assign_range, clear, emplace, erase, insert, insert_range, pop_back, resize и swap.
Следующие функции-члены могут инвалидировать только итератор end: append_range, emplace_back, push_back, try_emplace_back, try_push_back, unchecked_emplace_back и unchecked_push_back.
Параметры шаблона
| T | - | тип элемента |
| N | - | ёмкость, то есть максимальное количество элементов в inplace_vector (может быть 0). |
Типы-члены
| Тип | Определение |
|---|---|
value_type |
T |
size_type |
std::size_t |
difference_type |
std::ptrdiff_t |
reference | value_type& |
const_reference | constvalue_type& |
pointer | value_type* |
const_pointer | constvalue_type* |
iterator | определяемый реализацией LegacyRandomAccessIterator и random_access_iterator для value_type |
const_iterator | определяемый реализацией LegacyRandomAccessIterator, ConstexprIterator и random_access_iterator для constvalue_type |
reverse_iterator | std::reverse_iterator<iterator> |
const_reverse_iterator | std::reverse_iterator<const_iterator> |
Функции-члены
конструирует inplace_vector (функция-член открытого доступа) |
|
разрушает inplace_vector (функция-член открытого доступа) |
|
| присваивает контейнеру значения (функция-член открытого доступа) |
|
| присваивает контейнеру значения (функция-член открытого доступа) |
|
| присваивает контейнеру диапазон значений (функция-член открытого доступа) |
|
Доступ к элементам |
|
| доступ к указанному элементу с проверкой границ (функция-член открытого доступа) |
|
| доступ к указанному элементу (функция-член открытого доступа) |
|
| доступ к первому элементу (функция-член открытого доступа) |
|
| доступ к последнему элементу (функция-член открытого доступа) |
|
| прямой доступ к базовому непрерывному хранилищу (функция-член открытого доступа) |
|
Итераторы |
|
| возвращает итератор на начало (функция-член открытого доступа) |
|
| возвращает итератор на конец (функция-член открытого доступа) |
|
| возвращает обратный итератор на начало (функция-член открытого доступа) |
|
| возвращает обратный итератор на конец (функция-член открытого доступа) |
|
Размер и ёмкость |
|
| проверяет, пуст ли контейнер (функция-член открытого доступа) |
|
| возвращает количество элементов (функция-член открытого доступа) |
|
|
[static] | возвращает максимально возможное количество элементов (статическая функция-член открытого доступа) |
|
[static] | возвращает количество элементов, которое может храниться в выделенном в данный момент хранилище (статическая функция-член открытого доступа) |
| изменяет количество хранимых элементов (функция-член открытого доступа) |
|
|
[static] | резервирует хранилище (статическая функция-член открытого доступа) |
|
[static] | уменьшает использование памяти, освобождая неиспользуемую память (статическая функция-член открытого доступа) |
Модификаторы |
|
| вставляет элементы (функция-член открытого доступа) |
|
| вставляет диапазон элементов (функция-член открытого доступа) |
|
| конструирует элемент на месте (функция-член открытого доступа) |
|
| конструирует элемент на месте в конце (функция-член открытого доступа) |
|
| пытается сконструировать элемент на месте в конце (функция-член открытого доступа) |
|
| безусловно конструирует элемент на месте в конце (функция-член открытого доступа) |
|
| добавляет элемент в конец (функция-член открытого доступа) |
|
| пытается добавить элемент в конец (функция-член открытого доступа) |
|
| безусловно добавляет элемент в конец (функция-член открытого доступа) |
|
| удаляет последний элемент (функция-член открытого доступа) |
|
| добавляет диапазон элементов в конец (функция-член открытого доступа) |
|
| очищает содержимое (функция-член открытого доступа) |
|
| удаляет элементы (функция-член открытого доступа) |
|
| обменивает содержимое (функция-член открытого доступа) |
|
Функции, не являющиеся членами
|
(C++26) | специализирует алгоритм std::swap (шаблон функции) |
|
(C++26) | удаляет все элементы, соответствующие заданным критериям (шаблон функции) |
|
(C++26) | лексикографически сравнивает значения двух inplace_vector (шаблон функции) |
Примечания
Количество элементов в inplace_vector может динамически изменяться вплоть до фиксированной ёмкости, поскольку элементы хранятся непосредственно в самом объекте, подобно std::array. Однако объекты инициализируются по мере их вставки в inplace_vector, в отличие от C-массивов или std::array, в которых при создании должны конструироваться все элементы.
inplace_vector полезен в средах, где нежелательно динамическое выделение памяти.
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_inplace_vector | 202406L | (C++26) |
std::inplace_vector: динамически изменяемый вектор с фиксированной ёмкостью и хранилищем внутри объекта |
202603L | (C++26) | Улучшенный тип возвращаемого значения для try_push_back() и try_emplace_back(). try_append_range() удалён |
|
__cpp_lib_constexpr_inplace_vector | 202502L | (C++26) | Возможность вычисления std::inplace_vector во время компиляции для нетривиальных типов элементов |
Пример
#include <algorithm>
#include <array>
#include <cassert>
#include <inplace_vector>
#include <optional>
int main()
{
std::inplace_vector<int, 4> v1{0, 1, 2};
assert(v1.max_size() == 4);
assert(v1.capacity() == 4);
assert(v1.size() == 3);
assert(std::ranges::equal(v1, std::array{0, 1, 2}));
assert(v1[0] == 0);
assert(v1.at(0) == 0);
assert(v1.front() == 0);
assert(*v1.begin() == 0);
assert(v1.back() == 2);
v1.push_back(3);
assert(v1.back() == 3);
assert(std::ranges::equal(v1, std::array{0, 1, 2, 3}));
v1.resize(3);
assert(std::ranges::equal(v1, std::array{0, 1, 2}));
assert(v1.try_push_back(3) != std::nullopt);
assert(v1.back() == 3);
assert(v1.size() == 4);
assert(v1.try_push_back(13) == std::nullopt); // no place
assert(v1.back() == 3);
assert(v1.size() == 4);
v1.clear();
assert(v1.size() == 0);
assert(v1.empty());
}
См. также
| изменяемый массив с непрерывным хранением (шаблон класса) |
|
|
(C++11) | массив фиксированного размера с непрерывным хранением внутри объекта (шаблон класса) |
| двусторонняя очередь (шаблон класса) |
Внешние ссылки
| 1. |
inplace_vector — Эталонная реализация P0843R14 (std::inplace_vector). |
| 2. |
static_vector — Boost.Container реализует вектор с хранением внутри объекта как отдельный тип с собственными гарантиями. |
| 3. |
fixed_vector — EASTL реализует вектор с хранением внутри объекта с помощью дополнительного параметра шаблона. |
| 4. |
small_vector — Folly также реализует вектор с хранением внутри объекта с помощью дополнительного параметра шаблона. |
| 5. |
stack_alloc — пользовательские аллокаторы Howard Hinnant, имитирующие std::inplace_vector на основе std::vector. |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/inplace_vector