C++ named requirements: AllocatorAwareContainer (since C++11)
An AllocatorAwareContainer is a Container that holds an instance of an Allocator and uses that instance in all its member functions to allocate and deallocate memory and to construct and destroy objects in that memory (such objects may be container elements, nodes, or, for unordered containers, bucket arrays), except that std::basic_string specializations do not use the allocators for construction/destruction of their elements(since C++23).
The following rules apply to container construction:
- Copy constructors of AllocatorAwareContainers obtain their instances of the allocator by calling
std::allocator_traits<allocator_type>::select_on_container_copy_constructionon the allocator of the container being copied. - Move constructors obtain their instances of allocators by move-constructing from the allocator belonging to the old container.
- All other constructors take a
const allocator_type¶meter.
The only way to replace an allocator is copy-assignment, move-assignment, and swap:
- Copy-assignment will replace the allocator only if
std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::valueistrue. - Move-assignment will replace the allocator only if
std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::valueistrue. - Swap will replace the allocator only if
std::allocator_traits<allocator_type>::propagate_on_container_swap::valueistrue. Specifically, it will exchange the allocator instances through an unqualified call to the non-member function swap, see Swappable.
Note: swapping two containers with unequal allocators if propagate_on_container_swap is false is undefined behavior.
- The accessor
get_allocator()obtains a copy of the allocator that was used to construct the container or installed by the most recent allocator replacement operation.
Требования
Легенда
X | Тип контейнера |
T | Тип элемента |
A | Алокатор для T |
a, b | Объекты типа X (неконстантное левое значение) |
t | Объект типа X (левое значение или константное правое значение) |
rv | Объект типа X (неконстантное правое значение) |
m | Объект типа A |
Типы
| Выражение | Тип возвращаемого значения | Требования |
|---|---|---|
allocator_type | A |
allocator_type::value_type должен быть таким же, как X::value_type |
Члены-функции и операторы
| Выражение | Тип возвращаемого значения | Пред/требования | После/эффекты | Сложность |
|---|---|---|---|---|
get_allocator() | A | Постоянная | ||
X u; |
A является DefaultConstructible
| u.empty() == true && u.get_allocator() == A() | Постоянная | |
X u(m); | u.empty() == true && u.get_allocator() == m | Постоянная | ||
X u(t,m); |
T является CopyInsertable в X | u == t && u.get_allocator() == m | Линейная | |
X u(rv); | Конструктор перемещения A не должен выбрасывать исключения |
u содержит те же элементы и такой же алокатор, как и rv до построения | Постоянная | |
X u(rv,m); |
T является MoveInsertable в X | Элементы u такие же, или копии тех, что в rv, и u.get_allocator() == m | Постоянная, если m == rv.get_allocator(), иначе линейная |
|
a = t |
X& |
T является CopyInsertable в X и CopyAssignable
| a == t | Линейная |
a = rv |
X& | Если алокатор не будет заменён операцией перемещения (см. выше), то T является MoveInsertable в X и MoveAssignable | Все существующие элементы a либо перемещены, либо уничтожены; если a и rv не ссылаются на один и тот же объект, то a равно значению, которое rv имело до присваивания | Линейная |
a.swap(b) | void | Меняет содержимое a и b
| Постоянная |
Примечания
Контейнеры, учитывающие алокатор, всегда вызывают 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 являются AllocatorAwareContainers:
-
std::basic_string -
std::deque -
std::forward_list -
std::list -
std::vector -
std::map -
std::multimap -
std::set -
std::multiset -
std::unordered_map -
std::unordered_multimap -
std::unordered_set -
std::unordered_multiset
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| LWG 2839 | C++11 | Самоперемещение присваивания стандартных контейнеров не разрешалось | Разрешено, но результат не определён |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer