节点句柄 (C++17)
template</* 未指定 */> class /*node-handle*/; | (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
)的非 const 访问。如果节点句柄在持有节点时析构,那么就会用容器的分配器正确地析构节点。节点句柄含有容器分配器的副本,这是节点句柄能在容器生存期外存在所必需的。
节点句柄的确切类型(此处显示为 /*node-handle*/)是未指定的,但每个容器通过它的成员 node_type
暴露它的节点句柄类型。
节点句柄能用于在两个有相同键、值和分配器类型(忽略比较或散列/相等性)的关联容器间传递节点的所有权,而无需调用任何容器元素上的复制/移动操作(这种操作被称为“接合”)。在唯一和非唯一容器间传递也是容许的:来自 std::map 的节点句柄可被插入 std::multimap,但不能插入 std::unordered_map 或 std::set。
节点句柄可以为空,这种情况下它不保有元素和分配器。默认构造和被移动后的节点句柄是空的。另外,空的节点句柄可由对容器成员函数 extract
的失败调用产生。
如果成功将元素插入容器,那么在该元素被节点句柄占有期间获得的到该元素的引用或指针会失效。
对于所有 key_type
是 K
而 mapped_type
是 T
的映射容器(std::map、std::multimap、std::unordered_map 及 std::unordered_multimap),如果对 std::pair<K, T> 或 std::pair<const K, T> 存在 std::pair 的用户定义特化,那么涉及节点句柄的操作行为未定义。
成员类型
类型 | 定义 |
key_type (仅限 map 容器) | 在节点存储的关键 |
mapped_type (仅限 map 容器) | 在节点存储的元素的被映射部分 |
value_type (仅限集合容器) | 节点中存储的元素 |
allocator_type | 销毁元素时使用的分配器 |
container_node_type (私有) | 未指明类型的容器节点 (仅用于阐述的成员类型*) |
ator_traits (私有) | std::allocator_traits<allocator_type> 类型的分配器特征 (仅用于阐述的成员类型*) |
数据成员
成员 | 定义 |
typename ator_traits::template rebind_traits<container_node_type>::pointer ptr_ (有条件提供) | TODO (仅用于阐述的成员对象*) |
std::optional<allocator_type> alloc_ (有条件提供) | TODO (仅用于阐述的成员对象*) |
成员函数
构造函数
constexpr /*node-handle*/() noexcept; | (1) | |
/*node-handle*/ (/*node-handle*/&& nh) noexcept; | (2) | |
参数
nh | - | 同类型的节点句柄(不必属于相同容器) |
注解
节点句柄是仅移动的,不定义复制构造函数。
operator=
/*node-handle*/& operator=(/*node-handle*/&& nh); | ||
- 如果节点句柄非空,
- 那么通过调用 ator_traits::destroy 销毁此节点句柄管理的容器元素对象中的
value_type
子对象; - 通过调用 ator_traits::rebind_traits</*container-node-type*/>::deallocate 解分配容器元素;
- 那么通过调用 ator_traits::destroy 销毁此节点句柄管理的容器元素对象中的
- 从 nh 获得容器元素的所有权;
- 如果节点句柄为空(从而不含分配器)或 ator_traits::propagate_on_container_move_assignment 是 true,那么从 nh 移动赋值分配器;
- 设置 nh 为空状态。
如果节点非空且 ator_traits::propagate_on_container_move_assignment 是 false 且分配器比较不相等,那么行为未定义。
参数
nh | - | 同类型的节点句柄(不必属于相同容器) |
返回
*this
异常
不抛出。
注解
节点句柄是仅移动的,不定义复制赋值。
析构函数
~/*node-handle*/(); | ||
- 如果节点句柄非空,
- 那么通过调用 ator_traits::destroy,销毁此节点句柄管理的容器元素对象中的
value_type
子对象; - 通过调用 ator_traits::rebind_traits</*container-node-type*/>::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; | (仅限集合容器) | |
返回到此节点句柄管理的容器元素对象中的 value_type
子对象的引用。节点句柄为空时行为未定义。
异常
不抛出。
key
key_type& key() const; | (仅限映射容器) | |
返回到此节句柄柄管理的容器元素对象中的 value_type
子对象的 key_type
成员的非 const 引用。节点句柄为空时行为未定义。
异常
不抛出。
注解
此函数使得能够修改从映射提取的节点的键,再重新插入到映射,而无需复制或移动元素。
mapped
mapped_type& mapped() const; | (仅限映射容器) | |
返回到此节点句柄管理的容器元素对象中的 value_type
子对象的 mapped_type
成员的引用。节点句柄为空时行为未定义。
异常
不抛出。
swap
void swap(/*node-handle*/& nh) noexcept(/* 见下文 */); | ||
- 交换容器节点的所有权;
- 如果一个节点为空或两个节点均为非空且 ator_traits::propagate_on_container_swap 是 true,那么一同交换分配器。
如果两个节点均为非空且 ator_traits::propagate_on_container_swap 是 false 而分配器比较不相等,那么行为未定义。
异常
ator_traits::is_always_equal::value)