std::allocator

来自cppreference.com
< cpp‎ | memory
 
 
动态内存管理
未初始化内存算法
受约束的未初始化内存算法
分配器
allocator
垃圾收集支持
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)



 
 
在标头 <memory> 定义
template< class T >
struct allocator;
(1)
template<>
struct allocator<void>;
(2) (C++17 中弃用)
(C++20 中移除)

如果不提供用户指定的分配器,那么 std::allocator 类模板是所有标准库容器使用的默认分配器 (Allocator) 。默认分配器无状态,即任何给定的 allocator 实例可交换、比较相等,且能由同一 allocator 类型的任何其他实例释放分配的内存。

void 的显式特化缺少成员类型定义(typedef)referenceconst_referencesize_typedifference_type。此特化不声明成员函数。

(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
{
    typedef allocator<U> other;
};

is_always_equal(C++11)(C++23 中弃用) std::true_type

成员函数

创建新的 allocator 实例
(公开成员函数)
析构 allocator 实例
(公开成员函数)
(C++20 前)
获得对象的地址,即使重载了 operator&
(公开成员函数)
分配未初始化的存储
(公开成员函数)
分配与请求的大小至少一样大的未初始化存储
(公开成员函数)
解分配存储
(公开成员函数)
(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>>,它在 Astd::allocator 时以 A::rebind<Node<T>>::other (C++11 起) 实现。

成员类型 is_always_equalLWG 问题 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

参阅

提供关于分配器类型的信息
(类模板)
为多级容器实现的多级分配器
(类模板)
检查指定的类型是否支持使用分配器的构造
(类模板)