C++ named requirements: AllocatorAwareContainer (since C++11)
AllocatorAwareContainer — это Container , который хранит экземпляр Allocator и использует этот экземпляр во всех своих функциях-членах для выделения и освобождения памяти, а также для создания и уничтожения объектов в этой памяти (такие объекты могут быть элементами контейнера, узлами или, для неупорядоченных контейнеров, массивами корзин) , за исключением того, что специализации std::basic_string не используют аллокаторы для создания/уничтожения своих элементов (начиная с C++23) .
Следующие правила применяются к конструированию контейнеров:
- Конструкторы копирования AllocatorAwareContainer получают свои экземпляры аллокатора путем вызова std:: allocator_traits < allocator_type > :: select_on_container_copy_construction на аллокаторе копируемого контейнера.
- Конструкторы перемещения получают свои экземпляры аллокаторов путем перемещающего конструирования из аллокатора, принадлежащего старому контейнеру.
- Все остальные конструкторы принимают параметр const allocator_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 . Если обмен не распространяет аллокатор, обмен двух контейнеров с неравными аллокаторами является неопределенным поведением.
-
Метод доступа
get_allocator()получает копию аллокатора, который был использован для создания контейнера или установлен последней операцией замены аллокатора.
Единственным исключением является std:: basic_string < CharT,Traits,Allocator > :: assign , который также может распространять аллокатор.
Содержание |
Требования
Тип удовлетворяет требованиям AllocatorAwareContainer если он удовлетворяет требованиям Container и, при наличии следующих типов и значений, выполняются семантические требования и требования к сложности, приведенные в таблицах ниже:
| Тип | Определение |
X
|
тип AllocatorAwareContainer |
T
|
value_type
контейнера
X
|
A
|
тип аллокатора, используемого
X
|
| Значение | Определение |
| a , b |
неконстантные lvalue типа
X
|
| c | lvalue типа const X |
| t |
lvalue или константная rvalue типа
X
|
| rv |
неконстантная rvalue типа
X
|
| m |
значение типа
A
|
Типы
| Название | Тип | Требование |
|---|---|---|
| typename X :: 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
является
CopyInsertable
в
X
.
|
Линейная |
| Постусловие | u == t и u. get_allocator ( ) == m оба равны true . | ||
| X u ( rv ) ; | Постусловие |
|
Константная |
| X u ( rv, m ) ; | Предусловие |
T
является
MoveInsertable
в
X
.
|
|
| Постусловие |
|
||
Выражения
| Выражение | Тип | Семантика | Сложность | |
|---|---|---|---|---|
| c. get_allocator ( ) |
A
|
Нет прямого семантического требования. | Константная | |
| a = t |
X&
|
Предусловие |
T
должен быть
CopyInsertable
в
X
и
CopyAssignable
.
|
Линейная |
| Постусловие | a == t равно true . | |||
| a = rv |
X&
|
Предусловие |
Если аллокатор
не
будет заменен при перемещающем присваивании (см.
выше
), то
T
должен быть
MoveInsertable
в
X
и
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 :
|
хранит и манипулирует последовательностями символов
(шаблон класса) |
|
|
двусторонняя очередь
(шаблон класса) |
|
|
(C++11)
|
односвязный список
(шаблон класса) |
|
двусвязный список
(шаблон класса) |
|
|
изменяемый непрерывный массив
(шаблон класса) |
|
|
коллекция пар ключ-значение, отсортированная по ключам, ключи уникальны
(шаблон класса) |
|
|
коллекция пар ключ-значение, отсортированная по ключам
(шаблон класса) |
|
|
коллекция уникальных ключей, отсортированная по ключам
(шаблон класса) |
|
|
коллекция ключей, отсортированная по ключам
(шаблон класса) |
|
|
(C++11)
|
коллекция пар ключ-значение, хэшированная по ключам, ключи уникальны
(шаблон класса) |
|
(C++11)
|
коллекция пар ключ-значение, хэшированная по ключам
(шаблон класса) |
|
(C++11)
|
коллекция уникальных ключей, хэшированная по ключам
(шаблон класса) |
|
(C++11)
|
коллекция ключей, хэшированная по ключам
(шаблон класса) |
Отчёты о дефектах
Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 2839 | C++11 | self move assignment of standard containers was not allowed | allowed but the result is unspecified |