std::allocator
来自cppreference.com
在标头 <memory> 定义
|
||
template< class T > struct allocator; |
(1) | |
template<> struct allocator<void>; |
(2) | (C++17 中弃用) (C++20 中移除) |
如果不提供用户指定的分配器,那么 std::allocator
类模板是所有标准库容器使用的默认分配器 (Allocator) 。默认分配器无状态,即任何给定的 allocator 实例可交换、比较相等,且能由同一 allocator 类型的任何其他实例释放分配的内存。
对 void 的显式特化缺少成员类型定义(typedef) |
(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 |
成员函数
创建新的 allocator 实例 (公开成员函数) | |
析构 allocator 实例 (公开成员函数) | |
(C++20 前) |
获得对象的地址,即使重载了 operator& (公开成员函数) |
分配未初始化的存储 (公开成员函数) | |
(C++23) |
分配与请求的大小至少一样大的未初始化存储 (公开成员函数) |
解分配存储 (公开成员函数) | |
(C++17 中弃用)(C++20 中移除) |
返回最大的受支持分配大小 (公开成员函数) |
(C++17 中弃用)(C++20 中移除) |
在分配的存储构造对象 (公开成员函数) |
(C++17 中弃用)(C++20 中移除) |
析构在已分配存储中的对象 (公开成员函数) |
非成员函数
(C++20 中移除) |
比较两个分配器实例 (公开成员函数) |
注解
成员模板 rebind
提供获得不同类型的分配器的方式。例如,std::list<T, A> 在分配某个内部类型 Node<T>
节点时会使用分配器A::rebind<Node<T>>::other
(C++11 前)std::allocator_traits<A>::rebind_alloc<Node<T>>,它在 A
是 std::allocator
时以 A::rebind<Node<T>>::other
(C++11 起) 实现。
成员类型 is_always_equal
由 LWG 问题 3170 弃用,因为它使得派生自 std::allocator
的定制分配器默认被当作始终相等。std::allocator_traits<std::allocator<T>>::is_always_equal 未被弃用,而它的成员常量 value
对任何 T
均为 true。
示例
运行此代码
#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 的空间 // string 的默认分配器 std::allocator<std::string> alloc2; // 匹配的特征 using traits_t2 = std::allocator_traits<decltype(alloc2)>; // 用 string 的特征重绑定产生同一类型 traits_t2::rebind_alloc<std::string> alloc_ = alloc2; std::string* p2 = traits_t2::allocate(alloc2, 2); // 2 个 string 的空间 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) |
检查指定的类型是否支持使用分配器的构造 (类模板) |