std::allocator
Определено в заголовочном файле <memory>
|
||
template< class T > struct allocator; |
(1) | |
template<> struct allocator<void>; |
(2) | (устарело в C++17) (удалено в C++20) |
Шаблонный класс std::allocator
является Allocator
по умолчанию и используется всеми контейнерами стандартной библиотеки, если не указан пользовательский аллокатор. Аллокатор по умолчанию не имеет состояния, то есть все экземпляры данного аллокатора взаимозаменяемы, равны и могут освобождать память, выделенную любым другим экземпляром аллокатора того же типа.
В явной специализации для void отсутствуют определения типов элементов |
(до C++20) |
Распределитель по умолчанию соответствует требованиям к полноте аллокатора. |
(начиная с C++17) |
Содержание |
[править] Типы-элементы
Тип | Определение |
value_type
|
T
|
pointer (устарело в C++17)(удалено в C++20)
|
T*
|
const_pointer (устарело в C++17)(удалено в C++20)
|
const T* |
reference (устарело в C++17)(удалено в C++20)
|
T&
|
const_reference (устарело в C++17)(удалено в C++20)
|
const T& |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
propagate_on_container_move_assignment (C++11)
|
std::true_type |
rebind (устарело в C++17)(удалено в C++20)
|
template< class U > struct rebind |
is_always_equal (C++11)(устарело в C++23)
|
std::true_type |
[править] Функции-элементы
создаёт новый экземпляр аллокатора (public функция-элемент) | |
уничтожает экземпляр аллокатора (public функция-элемент) | |
(до C++20) |
получает адрес объекта, даже если operator& перегружен (public функция-элемент) |
выделяет неинициализированное хранилище (public функция-элемент) | |
(C++23) |
выделяет неинициализированное хранилище как минимум такого же размера, как запрошенный размер (public функция-элемент) |
освобождает память (public функция-элемент) | |
(до C++20) |
возвращает наибольший поддерживаемый размер распределения (public функция-элемент) |
(до C++20) |
создаёт объект в выделенном хранилище (public функция-элемент) |
(до C++20) |
уничтожает объект в выделенном хранилище (public функция-элемент) |
[править] Функции, не являющиеся элементами
(удалено в C++20) |
сравнивает два экземпляра аллокатора (public функция-элемент) |
[править] Примечание
Шаблонный класс элемента rebind
предоставляет способ получить аллокатор для другого типа. Например, std::list<T, A> распределяет узлы некоторого внутреннего типа Node<T>
, используя аллокатор A::rebind<Node<T>>::other
(до C++11)std::allocator_traits<A>::rebind_alloc<Node<T>>, который реализуется в терминах A::rebind<Node<T>>::other
, если A является std::allocator
(начиная с C++11).
Тип элемента is_always_equal
устарел в следствии LWG проблема 3170, поскольку он делает пользовательские распределители, производные от std::allocator
, по умолчанию всегда равными. std::allocator_traits<std::allocator<T>>::is_always_equal не устарел, а его константа-элемент value
равна true для любого T
.
[править] Пример
#include <memory> #include <iostream> #include <string> int main() { // аллокатор по умолчанию для int std::allocator<int> alloc1; // демонстрация нескольких непосредственно используемых элементов static_assert(std::is_same_v<int, decltype(alloc1)::value_type>); int* p1 = alloc1.allocate(1); // место для одного int alloc1.deallocate(p1, 1); // и его больше нет // Их даже можно использовать через свойства, но нет такой необходимости using traits_t1 = std::allocator_traits<decltype(alloc1)>; // Соответствующее свойство p1 = traits_t1::allocate(alloc1, 1); traits_t1::construct(alloc1, p1, 7); // создаём int std::cout << *p1 << '\n'; traits_t1::deallocate(alloc1, p1, 1); // освободить место для одного int // аллокатор по умолчанию для строк std::allocator<std::string> alloc2; // соответствующее свойство using traits_t2 = std::allocator_traits<decltype(alloc2)>; // Перепривязка аллокатора с помощью свойства для строк получает тот же тип traits_t2::rebind_alloc<std::string> alloc_ = alloc2; std::string* p2 = traits_t2::allocate(alloc2, 2); // место для 2 строк traits_t2::construct(alloc2, p2, "foo"); traits_t2::construct(alloc2, p2 + 1, "bar"); std::cout << p2[0] << ' ' << p2[1] << '\n'; traits_t2::destroy(alloc2, p2 + 1); traits_t2::destroy(alloc2, p2); traits_t2::deallocate(alloc2, p2, 2); }
Вывод:
7 foo bar
[править] Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
Номер | Применён | Поведение в стандарте | Корректное поведение |
---|---|---|---|
LWG 2103 | C++11 | может потребоваться избыточное сравнение между allocator
|
предоставленоpropagate_on_container_move_assignment
|
LWG 2108 | C++11 | не было способа показать, что allocator не имеет состояния
|
предоставлено is_always_equal
|
[править] Смотрите также
(C++11) |
предоставляет информацию о типах аллокаторов (шаблон класса) |
(C++11) |
реализует многоуровневый аллокатор для многоуровневых контейнеров (шаблон класса) |
(C++11) |
проверяет, поддерживает ли указанный тип конструирование с uses_allocator (шаблон класса) |