跳到主要内容

std::allocator

定义于内存
// 1)
template< class T >
struct allocator;
// 2)
template<>
struct allocator<void>; // Deprecated in C++17, Removed in C++20

std::allocator 类模板是所有标准库容器在未提供用户指定分配器时使用的默认 分配器。默认分配器是无状态的,即给定分配器的所有实例都可以互换,比较相等,并且可以释放由同一分配器类型的任何其他实例分配的内存。

void 的显式特化缺少成员 typedefs reference、const_reference、size_type 和 difference_type。此特化不声明任何成员函数 (直到 C++20) 默认分配器满足分配器完整性要求 (自 C++17 起)

成员类型

公共类型定义
公共value_typeT
公共pointer (在 C++20 中移除)T*
公共const_pointer (在 C++20 中移除)const T*
公共reference (在 C++20 中移除)T&
公共const_reference (在 C++20 中移除)const T&
公共size_typestd::ptrdiff_t
公共difference_typestd::ptrdiff_t
公共propagate_on_container_move_assignment (自 C++11 起)std::true_type
公共rebind (在 C++20 中移除)
template< class U >
struct rebind{
typedef allocator<U> other;
};
公共is_always_equal (自 C++11 起)std::true_type

成员函数

公共(构造函数)创建新的分配器实例
公共(析构函数)销毁分配器实例
公共address (直到 C++20)获取对象的地址,即使 operator& 被重载
公共allocate分配未初始化存储
公共allocate_at_least (自 C++23 起)分配至少与请求大小相同的未初始化存储
公共deallocate释放存储
公共max_size (直到 C++20)返回支持的最大分配大小
公共构造 (直到 C++20)在已分配存储中构造对象
公共addrdestroyess (直到 C++20)在已分配存储中销毁对象

非成员函数

公共operator==
operator!= (在 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&lt;Node&lt;T>>::other 实现 (自 C++11 起)

成员类型 is_always_equal 通过 LWG issue 3170 被弃用,因为它导致从 std::allocator 派生的自定义分配器默认被视为始终相等。std::allocator_traits<std::allocator<T>>::is_always_equal 未被弃用,并且其成员常量值对于任何 T 都为 true。

示例

#include <memory>
#include <iostream>
#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 2103C++11可能需要分配器之间冗余的比较提供了 propagate_on_container_move_assignment
LWG 2108C++11没有办法表明分配器是无状态的提供了 is_always_equal

std::allocator

定义于内存
// 1)
template< class T >
struct allocator;
// 2)
template<>
struct allocator<void>; // Deprecated in C++17, Removed in C++20

std::allocator 类模板是所有标准库容器在未提供用户指定分配器时使用的默认 分配器。默认分配器是无状态的,即给定分配器的所有实例都可以互换,比较相等,并且可以释放由同一分配器类型的任何其他实例分配的内存。

void 的显式特化缺少成员 typedefs reference、const_reference、size_type 和 difference_type。此特化不声明任何成员函数 (直到 C++20) 默认分配器满足分配器完整性要求 (自 C++17 起)

成员类型

公共类型定义
公共value_typeT
公共pointer (在 C++20 中移除)T*
公共const_pointer (在 C++20 中移除)const T*
公共reference (在 C++20 中移除)T&
公共const_reference (在 C++20 中移除)const T&
公共size_typestd::ptrdiff_t
公共difference_typestd::ptrdiff_t
公共propagate_on_container_move_assignment (自 C++11 起)std::true_type
公共rebind (在 C++20 中移除)
template< class U >
struct rebind{
typedef allocator<U> other;
};
公共is_always_equal (自 C++11 起)std::true_type

成员函数

公共(构造函数)创建新的分配器实例
公共(析构函数)销毁分配器实例
公共address (直到 C++20)获取对象的地址,即使 operator& 被重载
公共allocate分配未初始化存储
公共allocate_at_least (自 C++23 起)分配至少与请求大小相同的未初始化存储
公共deallocate释放存储
公共max_size (直到 C++20)返回支持的最大分配大小
公共构造 (直到 C++20)在已分配存储中构造对象
公共addrdestroyess (直到 C++20)在已分配存储中销毁对象

非成员函数

公共operator==
operator!= (在 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&lt;Node&lt;T>>::other 实现 (自 C++11 起)

成员类型 is_always_equal 通过 LWG issue 3170 被弃用,因为它导致从 std::allocator 派生的自定义分配器默认被视为始终相等。std::allocator_traits<std::allocator<T>>::is_always_equal 未被弃用,并且其成员常量值对于任何 T 都为 true。

示例

#include <memory>
#include <iostream>
#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 2103C++11可能需要分配器之间冗余的比较提供了 propagate_on_container_move_assignment
LWG 2108C++11没有办法表明分配器是无状态的提供了 is_always_equal