std::allocator
来自 cppreference.cn
定义于头文件 <memory> |
||
template< class T > struct allocator; |
(1) | |
template<> struct allocator<void>; |
(2) | (在 C++17 中弃用) (在 C++20 中移除) |
std::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 中弃用)(在 C++26 中移除) |
std::true_type |
[编辑] 成员函数
创建一个新的分配器实例 (公有成员函数) | |
析构一个分配器实例 (公有成员函数) | |
(直到 C++20) |
获取对象的地址,即使 operator& 被重载 (公有成员函数) |
分配未初始化的存储 (公有成员函数) | |
(C++23) |
分配至少与请求大小一样大的未初始化存储 (公有成员函数) |
释放存储 (公有成员函数) | |
(直到 C++20) |
返回最大的支持分配大小 (公有成员函数) |
(直到 C++20) |
在已分配的存储中构造对象 (公有成员函数) |
(直到 C++20) |
destroy 在已分配的存储中析构对象 |
[编辑] 非成员函数
(在 C++20 中移除) |
比较两个分配器实例 (公有成员函数) |
[编辑] 注解
成员模板类 rebind
提供了一种获取不同类型的分配器的方法。 例如,std::list<T, A> 使用分配器 A::rebind<Node<T>>::other
(直到 C++11)std::allocator_traits<A>::rebind_alloc<Node<T>> 分配一些内部类型 Node<T>
的节点,如果 A 是 std::allocator
,则根据 A::rebind<Node<T>>::other
实现(自 C++11 起) 来分配一些内部类型 Node<T>
的节点。
成员类型 is_always_equal
通过 LWG issue 3170 被弃用,因为它使得从 std::allocator
派生的自定义分配器默认被视为始终相等。 std::allocator_traits<std::allocator<T>>::is_always_equal 未被弃用,并且对于任何 T
,其成员常量 value
为 true。
[编辑] 示例
运行此代码
#include <iostream> #include <memory> #include <string> int main() { // default allocator for ints std::allocator<int> alloc1; // demonstrating the few directly usable members static_assert(std::is_same_v<int, decltype(alloc1)::value_type>); int* p1 = alloc1.allocate(1); // space for one int alloc1.deallocate(p1, 1); // and it is gone // Even those can be used through traits though, so no need using traits_t1 = std::allocator_traits<decltype(alloc1)>; // The matching trait p1 = traits_t1::allocate(alloc1, 1); traits_t1::construct(alloc1, p1, 7); // construct the int std::cout << *p1 << '\n'; traits_t1::deallocate(alloc1, p1, 1); // deallocate space for one int // default allocator for strings std::allocator<std::string> alloc2; // matching traits using traits_t2 = std::allocator_traits<decltype(alloc2)>; // Rebinding the allocator using the trait for strings gets the same type traits_t2::rebind_alloc<std::string> alloc_ = alloc2; std::string* p2 = traits_t2::allocate(alloc2, 2); // space for 2 strings 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++ 标准。
DR | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
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 构造 (类模板) |