节点句柄 (C++17)
template</* 未指定 */> class /* 节点句柄 */; |
(自 C++17 起) (仅作演示*) |
|
关联容器 std::set、std::map、std::multiset、std::multimap、std::unordered_set、std::unordered_map、std::unordered_multiset、std::unordered_multimap 是基于节点的数据结构,它们的节点可以提取为未指定类型的对象,称为节点句柄。
节点句柄是一种仅可移动的类型,它拥有并提供对节点中存储的元素 (value_type
) 的访问,并提供对元素的键部分 (key_type
) 和元素的映射部分 (mapped_type
) 的非常量访问。如果节点句柄在持有节点时被销毁,则会使用容器的适当分配器正确销毁节点。节点句柄包含容器分配器的副本。这是必要的,以便节点句柄可以比容器更长寿。
节点句柄的确切类型(此处显示为 /*节点句柄*/)未指定,但每个容器都将其节点句柄类型公开为成员 node_type
。
节点句柄可用于在具有相同键、值和分配器类型的两个关联容器之间传输元素的所有权(忽略比较或哈希/相等性),而无需在容器元素上调用任何复制/移动操作(这种操作称为“拼接”)。也允许在唯一和非唯一容器之间传输:来自 std::map 的节点句柄可以插入到 std::multimap 中,但不能插入到 std::unordered_map 或 std::set 中。
节点句柄可能为空,在这种情况下,它不包含元素和分配器。默认构造和移动后的节点句柄为空。此外,空节点句柄可以通过对容器成员函数 extract
的失败调用产生。
当元素由节点句柄拥有时获得的指向元素的指针和引用,如果元素成功插入到容器中,则会失效。
对于所有映射容器(std::map、std::multimap、std::unordered_map 和 std::unordered_multimap),它们的 key_type
为 K
且 mapped_type
为 T
,如果存在 std::pair 的用户定义特化用于 std::pair<K, T> 或 std::pair<const K, T>,则涉及节点句柄的操作行为是未定义的。
目录 |
[编辑] 成员类型
类型 | 定义 |
key_type (仅限 map 容器) |
节点中存储的键 |
mapped_type (仅限 map 容器) |
节点中存储的元素的映射部分 |
value_type (仅限 set 容器) |
节点中存储的元素 |
allocator_type
|
销毁元素时要使用的分配器 |
container_node_type (私有) |
容器节点,类型未指定 (仅作演示的成员类型*) |
ator_traits (私有) |
类型为 std::allocator_traits<allocator_type> 的分配器特性 (仅作演示的成员类型*) |
[编辑] 数据成员
成员 | 定义 |
typename ator_traits::template rebind_traits<container_node_type>::pointer ptr_ (有条件地存在) |
待办事项 (仅作演示的成员对象*) |
std::optional<allocator_type> alloc_ (有条件地存在) |
待办事项 (仅作演示的成员对象*) |
[编辑] 成员函数
构造函数
constexpr /* 节点句柄 */() noexcept; |
(1) | |
/* 节点句柄 */(/* 节点句柄 */&& nh) noexcept; |
(2) | |
参数
nh | - | 具有相同类型的节点句柄(不一定是相同的容器) |
注释
节点句柄是仅可移动的,未定义复制构造函数。
operator=
/* 节点句柄 */& operator=(/* 节点句柄 */&& nh); |
||
- 如果节点句柄不为空,
- 通过调用
ator_traits::destroy
销毁此节点句柄管理的容器元素对象中的value_type
子对象; - 通过调用 ator_traits::rebind_traits</* 容器节点类型 */>::deallocate 解分配容器元素;
- 通过调用
- 从 nh 获取容器元素的所有权;
- 如果节点句柄为空(因此不包含分配器),或者如果 ator_traits::propagate_on_container_move_assignment 为 true,则从 nh 移动赋值分配器;
- 将 nh 设置为空状态。
如果节点不为空且 ator_traits::propagate_on_container_move_assignment 为 false 且分配器不相等,则行为未定义。
参数
nh | - | 具有相同类型的节点句柄(不一定是相同的容器) |
返回值
*this
异常
不抛出任何异常。
注释
节点句柄是仅可移动的,未定义复制赋值运算符。
析构函数
~/* 节点句柄 */(); |
||
- 如果节点句柄不为空,
- 通过调用 ator_traits::destroy 销毁此节点句柄管理的容器元素对象中的
value_type
子对象; - 通过调用 ator_traits::rebind_traits</* 容器节点类型 */>::deallocate 解分配容器元素。
- 通过调用 ator_traits::destroy 销毁此节点句柄管理的容器元素对象中的
empty
bool empty() const noexcept; |
||
如果节点句柄为空,则返回 true,否则返回 false。
operator bool
explicit operator bool() const noexcept; |
||
如果节点句柄为空,则转换为 false,否则转换为 true。
get_allocator
allocator_type get_allocator() const; |
||
返回存储的分配器的副本(它是源容器的分配器的副本)。如果节点句柄为空,则行为未定义。
异常
不抛出任何异常。
value
value_type& value() const; |
(仅限 set 容器) | |
返回对此节点句柄管理的容器元素对象中的 value_type
子对象的引用。如果节点句柄为空,则行为未定义。
异常
不抛出任何异常。
key
key_type& key() const; |
(仅限 map 容器) | |
返回对此节点句柄管理的容器元素对象中的 value_type
子对象的 key_type
成员的非常量引用。如果节点句柄为空,则行为未定义。
异常
不抛出任何异常。
注释
此函数使得可以修改从映射中提取的节点的键,然后将其重新插入到映射中,而无需复制或移动元素。
mapped
mapped_type& mapped() const; |
(仅限 map 容器) | |
返回对此节点句柄管理的容器元素对象中的 value_type
子对象的 mapped_type
成员的引用。如果节点句柄为空,则行为未定义。
异常
不抛出任何异常。
swap
void swap(/* 节点句柄 */& nh) noexcept(/* 见下文 */); |
||
- 交换容器节点的所有权;
- 如果一个节点为空,或者如果两个节点都不为空且 ator_traits::propagate_on_container_swap 为 true,则也交换分配器。
如果两个节点都不为空且 ator_traits::propagate_on_container_swap 为 false 且分配器不相等,则行为未定义。
异常
ator_traits::is_always_equal::value)