定义于头文件
- 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++11 前) |
| 自定义分配器可以含有状态。每个容器或其他具分配器对象存储一个提供的分配器实例,并通过 std::allocator_traits 控制分配器替换。 | (C++11 起) |
| 默认分配器满足分配器完整性要求。 | (C++17 起) |
std::allocator<T>::allocator
| allocator() throw(); | (1) | (C++11 前) |
| allocator() noexcept; | (C++11 起) (C++20 前) | |
| constexpr allocator() noexcept; | (C++20 起) | |
| allocator( const allocator& other ) throw(); | (2) | (C++11 前) |
| allocator( const allocator& other ) noexcept; | (C++11 起) (C++20 前) | |
| constexpr allocator( const allocator& other ) noexcept; | (C++20 起) | |
| template< class U > | (3) | (C++11 前) |
| template< class U > | (C++11 起) (C++20 前) | |
| template< class U > | (C++20 起) |
构造默认分配器。因为默认分配器是无状态的,故构造函数无可见效应。
| other | - | 用以构造的另一 allocator |
std::allocator<T>::~allocator
| ~allocator(); | (C++20 前) | |
| constexpr ~allocator(); | (C++20 起) |
销毁默认分配器。
std::allocator<T>::address
| pointer address( reference x ) const; | (C++11 前) | |
| pointer address( reference x ) const noexcept; | (C++11 起) (C++17 中弃用) (C++20 中移除) | |
| const_pointer address( const_reference x ) const; | (C++11 前) | |
| const_pointer address( const_reference x ) const noexcept; | (C++11 起) (C++17 中弃用) (C++20 中移除) |
返回 x 的实际地址,即使存在重载的 operator& 。
| x | - | 要获取地址的对象 |
x 的实际地址。
std::allocator<T>::allocate
| pointer allocate( size_type n, const void * hint = 0 ); | (1) | (C++17 前) |
| T* allocate( std::size_t n, const void * hint); | (C++17 起) (弃用) (C++20 中移除) | |
| T* allocate( std::size_t n ); | (2) | (C++17 起) (C++20 前) |
| [[nodiscard]] constexpr T* allocate( std::size_t n ); | (C++20 起) |
调用 ::operator new(std::size_t) 或 ::operator new(std::size_t, std::align_val_t) (C++17 起)分配 n * sizeof(T) 字节的未初始化存储,但何时及如何调用此函数是未指定的。指针 hint 可用于提供引用的局部性:若实现支持,则 allocator 会试图分配尽可能接近 hint 的新内存块。
| n | - | 要分配存储的对象数 |
| hint | - | 指向临近内存位置的指针 |
指向适当对齐并足以保有 T 类型的 n 个对象数组的内存块首字节的指针。
若分配失败则抛出 std::bad_alloc 。
遣词“未指定何时及如何”令标准库容器可以组合或优化掉堆分配,即使对直接调用 ::operator new 禁止这种优化。例如 libc++ 实现了它( [1] 与 [2] )
std::allocator<T>::deallocate
| void deallocate( T* p, std::size_t n ); | (C++20 前) | |
| constexpr void deallocate( T* p, std::size_t n ); | (C++20 起) |
从指针 p 所引用的存储解分配,指针必须是通过先前对 allocate() 获得的指针。
参数 n 必须等于对原先生成 p 的 allocate() 调用的首参数;否则行为未定义。
调用 ::operator delete(void*) 或 ::operator delete(void*, std::align_val_t) (C++17 起),但何时及如何调用是未指定的。
| p | - | 从 allocate() 获得的指针 |
| n | - | 先前传递给 allocate() 的对象数 |
(无)
- #include <memory>
- #include <iostream>
- #include <string>
-
- int main()
- {
- std::allocator<int> ai; // int 的默认分配器
- int* a = ai.allocate(10); // 10个 int 的空间
- for (int i = 0; i < 10; i++)
- {
- ai.construct(a + i, i); // 构造 int
- }
- for (int i = 0; i < 10; i++)
- {
- std::cout << a[i] << '\n';
- }
- ai.deallocate(a, 10); // 解分配10个 int 的空间
-
- std::allocator<std::string> as; // string 的默认分配器
- std::string * s = as.allocate(10); // 10个 string 的空间
- for (int i = 0; i < 10; i++)
- {
- as.construct(s + i, std::to_string(i) + "-string"); // 构造 int
- }
- for (int i = 0; i < 10; i++)
- {
- std::cout << s[i] << '\n';
- }
- as.deallocate(s, 10); // 解分配10个 int 的空间
- }
std::allocator<T>::max_size
| size_type max_size() const throw(); | (C++11 前) | |
| size_type max_size() const noexcept; | (C++11 起) (C++17 中弃用) (C++20 中移除) |
返回理论上可行的 n 最大值,对于它 allocate(n, 0) 调用可能成功。
大部分实现中,它返回 std::numeric_limits
(无)
受支持的最大分配大小
- #include <memory>
- #include <iostream>
- #include <string>
-
- struct Foo
- {
- Foo() {}
- };
-
- int main()
- {
- std::allocator<char> ac; // char 的默认分配器
- std::allocator<int> ai; // int 的默认分配器
- std::allocator<double> ad; // double 的默认分配器
- std::allocator<std::string> as; // string 的默认分配器
- std::allocator<Foo> af; // Foo 的默认分配器
- std::cout << "char max_size() " << ac.max_size() << '\n';
- std::cout << "int max_size() " << ai.max_size() << '\n';
- std::cout << "double max_size() " << ad.max_size() << '\n';
- std::cout << "as max_size() " << as.max_size() << '\n';
- std::cout << "Foo max_size() " << af.max_size() << '\n';
- }

std::allocator<T>::construct
| void construct( pointer p, const_reference val ); | (1) | (C++11 前) |
| template< class U, class... Args > | (2) | (C++11 起) (C++17 中弃用) (C++20 中移除) |
用布置 new ,在 p 所指的未初始化存储中构造 T 类型对象。
1) 调用 new((void *)p) T(val)
2) 调用 ::new((void *)p) U(std::forward
| p | - | 指向未初始化存储的指针 |
| val | - | 用作复制构造函数参数的值 |
| args... | - | 所用的构造函数参数 |
(无)
std::allocator<T>::destroy
| void destroy( pointer p ); | (C++11 前) | |
| template< class U > | (C++11 起) (C++17 中弃用) (C++20 中移除) |
调用 p 所指的对象的析构函数
1) 调用 ((T*)p)->~T()
2) 调用 p->~U()
| p | - | 指向要被销毁的对象的指针 |
(无)
operator==,!=(std::allocator)
| template< class T1, class T2 > | (1) | (C++11 前) |
| template< class T1, class T2 > | (C++11 起) (C++20 前) | |
| template< class T1, class T2 > | (C++20 起) | |
| template< class T1, class T2 > | (2) | (C++11 前) |
| template< class T1, class T2 > | (C++11 起) (C++20 前) |
比较二个默认分配器。因为默认分配器无状态,故二个默认分配器始终相等。
1) 返回 true
2) 返回 false
| lhs, rhs | - | 要比较的默认分配器 |
- #include <memory>
- #include <iostream>
- #include <string>
-
- int main()
- {
- std::allocator<int> a1; // int 的默认分配器
- int* a = a1.allocate(1); // 一个 int 的空间
- a1.construct(a, 7); // 构造 int
- std::cout << a[0] << '\n';
- a1.deallocate(a, 1); // 解分配一个 int 的空间
-
- // string 的默认分配器
- std::allocator<std::string> a2;
-
- // 同上,但以 a1 的重绑定获取
- decltype(a1)::rebind<std::string>::other a2_1;
-
- // 同上,但通过 allocator_traits 由类型 a1 的重绑定获取
- std::allocator_traits<decltype(a1)>::rebind_alloc<std::string> a2_2;
-
- std::string* s = a2.allocate(2); // 2 个 string 的空间
-
- a2.construct(s, "foo");
- a2.construct(s + 1, "bar");
-
- std::cout << s[0] << ' ' << s[1] << '\n';
-
- a2.destroy(s);
- a2.destroy(s + 1);
- a2.deallocate(s, 2);
- }