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);// создаём intstd::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 (шаблон класса) |