Spec-Zone.ru › C++

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>

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

(constructor)
конструирует inplace_vector
(функция-член открытого доступа)
(destructor)
разрушает inplace_vector
(функция-член открытого доступа)
operator=
присваивает контейнеру значения
(функция-член открытого доступа)
assign
присваивает контейнеру значения
(функция-член открытого доступа)
assign_range
присваивает контейнеру диапазон значений
(функция-член открытого доступа)
Доступ к элементам
at
доступ к указанному элементу с проверкой границ
(функция-член открытого доступа)
operator[]
доступ к указанному элементу
(функция-член открытого доступа)
front
доступ к первому элементу
(функция-член открытого доступа)
back
доступ к последнему элементу
(функция-член открытого доступа)
data
прямой доступ к базовому непрерывному хранилищу
(функция-член открытого доступа)
Итераторы
begincbegin
возвращает итератор на начало
(функция-член открытого доступа)
endcend
возвращает итератор на конец
(функция-член открытого доступа)
rbegincrbegin
возвращает обратный итератор на начало
(функция-член открытого доступа)
rendcrend
возвращает обратный итератор на конец
(функция-член открытого доступа)
Размер и ёмкость
empty
проверяет, пуст ли контейнер
(функция-член открытого доступа)
size
возвращает количество элементов
(функция-член открытого доступа)
max_size
[static]
возвращает максимально возможное количество элементов
(статическая функция-член открытого доступа)
capacity
[static]
возвращает количество элементов, которое может храниться в выделенном в данный момент хранилище
(статическая функция-член открытого доступа)
resize
изменяет количество хранимых элементов
(функция-член открытого доступа)
reserve
[static]
резервирует хранилище
(статическая функция-член открытого доступа)
shrink_to_fit
[static]
уменьшает использование памяти, освобождая неиспользуемую память
(статическая функция-член открытого доступа)
Модификаторы
insert
вставляет элементы
(функция-член открытого доступа)
insert_range
вставляет диапазон элементов
(функция-член открытого доступа)
emplace
конструирует элемент на месте
(функция-член открытого доступа)
emplace_back
конструирует элемент на месте в конце
(функция-член открытого доступа)
try_emplace_back
пытается сконструировать элемент на месте в конце
(функция-член открытого доступа)
unchecked_emplace_back
безусловно конструирует элемент на месте в конце
(функция-член открытого доступа)
push_back
добавляет элемент в конец
(функция-член открытого доступа)
try_push_back
пытается добавить элемент в конец
(функция-член открытого доступа)
unchecked_push_back
безусловно добавляет элемент в конец
(функция-член открытого доступа)
pop_back
удаляет последний элемент
(функция-член открытого доступа)
append_range
добавляет диапазон элементов в конец
(функция-член открытого доступа)
clear
очищает содержимое
(функция-член открытого доступа)
erase
удаляет элементы
(функция-член открытого доступа)
swap
обменивает содержимое
(функция-член открытого доступа)

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

std::swap(std::inplace_vector)
(C++26)
специализирует алгоритм std::swap
(шаблон функции)
erase(std::inplace_vector)erase_if(std::inplace_vector)
(C++26)
удаляет все элементы, соответствующие заданным критериям
(шаблон функции)
operator==operator<=>
(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());
}

См. также

vector
изменяемый массив с непрерывным хранением
(шаблон класса)
array
(C++11)
массив фиксированного размера с непрерывным хранением внутри объекта
(шаблон класса)
deque
двусторонняя очередь
(шаблон класса)

Внешние ссылки

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

Spec-Zone.ru

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