std:: allocator
|
定义于头文件
<memory>
|
||
|
template
<
class
T
>
struct allocator ; |
(1) | |
|
template
<>
struct allocator < void > ; |
(2) |
(C++17 中弃用)
(C++20 中移除) |
std::allocator
类模板是所有标准库容器在未提供用户指定分配器时使用的默认
分配器
。默认分配器是无状态的,这意味着给定分配器的所有实例可相互替换、比较相等,并且能够释放同一分配器类型任意其他实例所分配的内存。
|
针对
void
的显式特化缺少成员类型定义
|
(C++20 前) |
|
默认分配器满足 分配器完整性要求 。 |
(since 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 中弃用)
(C++26 中移除)
|
std::true_type |
成员函数
|
创建新的分配器实例
(公开成员函数) |
|
|
析构分配器实例
(公开成员函数) |
|
|
(until C++20)
|
获取对象地址,即使
operator
&
被重载
(公开成员函数) |
|
分配未初始化的存储空间
(公开成员函数) |
|
|
(C++23)
|
分配至少达到请求大小的未初始化存储空间
(公开成员函数) |
|
释放存储空间
(公开成员函数) |
|
|
(until C++20)
|
返回支持的最大分配大小
(公开成员函数) |
|
(until C++20)
|
在已分配的存储空间中构造对象
(公开成员函数) |
|
(until C++20)
|
析构已分配存储空间中的对象
(公开成员函数) |
非成员函数
|
(在 C++20 中移除)
|
比较两个分配器实例
(公开成员函数) |
注释
成员模板类
rebind
提供了一种获取适用于其他类型的分配器的方法。例如,
std::
list
<
T, A
>
会使用分配器
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 起)
来分配某种内部类型
Node<T>
的节点。
成员类型
is_always_equal
已通过
LWG 问题 3170
被弃用,因为它会导致派生自
std::allocator
的自定义分配器默认被视为始终相等。
std::
allocator_traits
<
std
::
allocator
<
T
>>
::
is_always_equal
未被弃用,且其成员常量
value
对任意
T
均为
true
。
示例
#include <iostream> #include <memory> #include <string> int main() { // 用于整型的默认分配器 std::allocator<int> alloc1; // 演示可直接使用的少数成员 static_assert(std::is_same_v<int, decltype(alloc1)::value_type>); int* p1 = alloc1.allocate(1); // 为一个整型分配空间 alloc1.deallocate(p1, 1); // 释放该空间 // 这些操作也可通过特性类实现,因此无需直接使用 using traits_t1 = std::allocator_traits<decltype(alloc1)>; // 匹配的特性类 p1 = traits_t1::allocate(alloc1, 1); traits_t1::construct(alloc1, p1, 7); // 构造整型对象 std::cout << *p1 << '\n'; traits_t1::deallocate(alloc1, p1, 1); // 释放一个整型空间 // 用于字符串的默认分配器 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); // 为两个字符串分配空间 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)
|
检查指定类型是否支持使用分配器构造
(类模板) |