# std::allocator

< cpp‎ | memory

定义于头文件 `<memory>` |  |
template< class T > struct allocator; | (1) |
template<> struct allocator<void>; | (2) | (C++17 中弃用) (C++20 中移除)

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

对 void 的显式特化缺少成员 typedef `reference` 、 `const_reference` 、 `size_type` 和 `difference_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++14) | std::true_type
`rebind` (C++17 中弃用)(C++20 中移除) | template< class U > struct rebind { typedef allocator<U> other; };
`is_always_equal`(C++17)(C++20 中弃用) | std::true_type

### 成员函数

(构造函数) | 创建新的 allocator 实例 (公开成员函数)
(析构函数) | 析构 allocator 实例 (公开成员函数)
address (C++17 中弃用)(C++20 中移除) | 获得对象的地址，即使重载了 operator& (公开成员函数)
allocate | 分配未初始化的存储 (公开成员函数)
allocate_at_least (C++23) | 分配与请求的大小至少一样大的未初始化存储 (公开成员函数)
deallocate | 解分配存储 (公开成员函数)
max_size (C++17 中弃用)(C++20 中移除) | 返回最大的受支持分配大小 (公开成员函数)
construct (C++17 中弃用)(C++20 中移除) | 在分配的存储构造对象 (公开成员函数)
destroy (C++17 中弃用)(C++20 中移除) | 析构在已分配存储中的对象 (公开成员函数)

### 非成员函数

operator==operator!= (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 <memory>
    #include <iostream>
    #include <string>

    int main()
    {
        {
            // int 的默认分配器
            std::allocator<int> alloc;

            // 演示少见的直接使用成员
            static_assert(std::is_same_v<int, decltype(alloc)::value_type>);
            int* p = alloc.allocate(1);  // 一个 int 的空间
            alloc.deallocate(p, 1);      // 而它没了

            // 即使可以通过特征使用这些，从而无直接使用的必要
            using traits_t = std::allocator_traits<decltype(alloc)>; // 匹配的特征
            p = traits_t::allocate(alloc, 1);
            traits_t::construct(alloc, p, 7);       // 构造 int
            std::cout << *p << '\n';
            traits_t::deallocate(alloc, p, 1);      // 解分配 int 的空间
        }

        {
            // string 的默认分配器
            std::allocator<std::string> alloc;
            // 匹配的特征
            using traits_t = std::allocator_traits<decltype(alloc)>;

            // 用 string 的特征重绑定产生同一类型
            traits_t::rebind_alloc<std::string> alloc_ = alloc;

            std::string* p = traits_t::allocate(alloc, 2); // 2 个 string 的空间

            traits_t::construct(alloc, p, "foo");
            traits_t::construct(alloc, p + 1, "bar");

            std::cout << p[0] << ' ' << p[1] << '\n';

            traits_t::destroy(alloc, p + 1);
            traits_t::destroy(alloc, p);
            traits_t::deallocate(alloc, p, 2);
        }
    }

输出：

    7
    foo bar

### 参阅

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