Spec-Zone.ru › C++

Именованные требования C++: AllocatorAwareContainer (начиная с C++11)

AllocatorAwareContainer — это контейнер, который содержит экземпляр аллокатора и использует этот экземпляр во всех своих функциях-членах для выделения и освобождения памяти, а также для конструирования и уничтожения объектов в этой памяти (такими объектами могут быть элементы контейнера, узлы или, для неупорядоченных контейнеров, массивы бакетов), за исключением специализаций std::basic_string, которые не используют аллокаторы для конструирования/уничтожения своих элементов(начиная с C++23).

При конструировании контейнера применяются следующие правила:

  • Конструкторы копирования AllocatorAwareContainer получают экземпляры аллокатора, вызывая std::allocator_traits<allocator_type>::select_on_container_copy_construction для аллокатора копируемого контейнера.
  • Конструкторы перемещения получают экземпляры аллокаторов, конструируя их перемещением из аллокатора старого контейнера.
  • Все остальные конструкторы принимают параметр constallocator_type&.

Единственный способ заменить аллокатор — это присваивание копированием, присваивание перемещением и обмен:

  • При присваивании копированием аллокатор будет заменён, только если std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value равно true.
  • При присваивании перемещением аллокатор будет заменён, только если std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value равно true.
  • При обмене аллокатор будет заменён, только если std::allocator_traits<allocator_type>::propagate_on_container_swap::value равно true. В частности, экземпляры аллокатора будут обменены посредством неквалифицированного вызова нешаблонной функции swap; см. Swappable.

Примечание: поведение при обмене двух контейнеров с неравными аллокаторами, если propagate_on_container_swap равно false, не определено.

  • Аксессор get_allocator() возвращает копию аллокатора, использованного для конструирования контейнера или установленного последней операцией замены аллокатора.

Требования

Тип удовлетворяет требованиям AllocatorAwareContainer, если он удовлетворяет требованиям Container и для следующих типов и значений соблюдаются семантические требования и требования к сложности, приведённые в таблицах ниже:

Тип Определение
X тип AllocatorAwareContainer
T value_type типа X
A тип аллокатора, используемый X
Значение Определение
a, b неконстантные lvalue типа X
c lvalue типа constX
t lvalue или константное rvalue типа X
rv неконстантное rvalue типа X
m значение типа A

Типы

Имя Тип Требование
typenameX::allocator_type A X::allocator_type::value_type и X::value_type совпадают.

Инструкции

Инструкция Семантика Сложность
X u;
X u = X();
Предусловие A удовлетворяет требованиям DefaultConstructible. Константная
Постусловие u.empty() и u.get_allocator() == A() оба равны true.
X u(m); Постусловие u.empty() и u.get_allocator() == m оба равны true. Константная
X u(t, m); Предусловие T можно вставить в X согласно требованиям CopyInsertable. Линейная
Постусловие u == t и u.get_allocator() == m оба равны true.
X u(rv); Постусловие
  • u содержит те же элементы, что и rv до этого конструирования.
  • Значение u.get_allocator() совпадает со значением rv.get_allocator() до этого конструирования.
Константная
X u(rv, m); Предусловие T можно вставить перемещением в X согласно требованиям MoveInsertable.
  • Константная, если m == rv.get_allocator() равно true.
  • В противном случае линейная.
Постусловие
  • u содержит те же элементы или копии элементов, которые были в rv до этого конструирования.
  • u.get_allocator() == m равно true.

Выражения

Выражение Тип Семантика Сложность
c.get_allocator() A Прямых семантических требований нет. Константная
a = t X& Предусловие T можно вставить в X согласно требованиям CopyInsertable, и оно удовлетворяет требованиям CopyAssignable. Линейная
Постусловие a == t равно true.
a = rv X& Предусловие Если аллокатор не будет заменён при присваивании перемещением (см. выше), то T можно вставить перемещением в X согласно требованиям MoveInsertable, и оно удовлетворяет требованиям MoveAssignable. Линейная
Эффект Всем существующим элементам a либо присваиваются значения перемещением, либо они уничтожаются.
Постусловие Если a и rv не ссылаются на один и тот же объект, a равно значению, которое rv имело до присваивания.
a.swap(b) void Эффект Обменивает содержимое a и b. Константная

Примечания

AllocatorAwareContainer всегда вызывает std::allocator_traits<A>::construct(m, p, args) для конструирования объекта типа T по адресу p с использованием args и m == get_allocator(). Стандартный construct в std::allocator вызывает ::new((void*)p) T(args)(до C++20 включительно)std::allocator не имеет члена construct, и при конструировании элементов вызывается std::construct_at(p, args)(начиная с C++20), однако специализированные аллокаторы могут определять это иначе.

Стандартная библиотека

Все строковые типы и контейнеры стандартной библиотеки (кроме std::array и std::inplace_vector) являются AllocatorAwareContainer:

basic_string
хранит и обрабатывает последовательности символов
(шаблон класса)
deque
двусторонняя очередь
(шаблон класса)
forward_list
(C++11)
односвязный список
(шаблон класса)
list
двусвязный список
(шаблон класса)
vector
изменяемый по размеру непрерывный массив
(шаблон класса)
map
набор пар «ключ-значение», упорядоченных по ключам; ключи уникальны
(шаблон класса)
multimap
набор пар «ключ-значение», упорядоченных по ключам
(шаблон класса)
set
набор уникальных ключей, упорядоченных по ключам
(шаблон класса)
multiset
набор ключей, упорядоченных по ключам
(шаблон класса)
unordered_map
(C++11)
набор пар «ключ-значение», хешируемых по ключам; ключи уникальны
(шаблон класса)
unordered_multimap
(C++11)
набор пар «ключ-значение», хешируемых по ключам
(шаблон класса)
unordered_set
(C++11)
набор уникальных ключей, хешируемых по ключам
(шаблон класса)
unordered_multiset
(C++11)
набор ключей, хешируемых по ключам
(шаблон класса)

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

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

DR Применён к Опубликованное поведение Корректное поведение
LWG 2839 C++11 самоприсваивание перемещением стандартных контейнеров не допускалось допускается, но результат не определён

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

Spec-Zone.ru

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