结点把柄 (C++17)
template</*unspecified*/> 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 (仅 set 容器)
|
存储于结点的元素 |
allocator_type
|
销毁元素时使用的分配器 |
成员函数
构造函数
constexpr /*node-handle*/() noexcept; |
(1) | |
/*node-handle*/(/*node-handle*/&& nh) noexcept; |
(2) | |
nh
取走容器元素所有权,移动构造成员分配器,并令 nh
留在空状态。参数
nh | - | 同类型的结点把柄(不必属于相同容器) |
注意
结点把柄是仅移动的,不定义复制构造函数。
operator=
/*node-handle*/& operator=(/*node-handle*/&& nh); |
||
- 若结点把柄非空,
- 则通过调用
std::allocator_traits<allocator_type>::destroy
,销毁此结点把柄所管理的容器元素对象中的value_type
子对象; - 通过调用
allocator_traits<allocator_type>::rebind_traits<container-node-type>::deallocate
解分配容器元素;
- 则通过调用
- 从
nh
获得容器元素的所有权; - 若结点把柄为空(从而不含分配器)或若
allocator_traits<allocator_type>::propagate_on_container_move_assignment
为true
,则从nh
移动赋值分配器; - 设置
nh
为空状态。
若结点非空且 allocator_traits<allocator_type>::propagate_on_container_move_assignment
为 false
且分配器比较不相等,则行为未定义。
参数
nh | - | 同类型的结点把柄(不必属于相同容器) |
返回
*this
异常
(无)
注意
结点把柄是仅移动的,不定义复制赋值。
析构函数
~/*node-handle*/(); |
||
- 若结点把柄非空,
- 则通过调用
std::allocator_traits<allocator_type>::destroy
,销毁此结点把柄所管理的容器元素对象中的value_type
子对象; - 通过调用
allocator_traits<allocator_type>::rebind_traits<container-node-type>::deallocate
解分配容器元素。
- 则通过调用
empty
bool empty() const noexcept; |
(C++20 前) | |
[[nodiscard]] bool empty() const noexcept; |
(C++20 起) | |
若结点把柄为空则返回 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
成员的非 const 引用。若结点把柄为空则行为未定义。
异常
(无)
注意
此函数使得能够修改从映射释出的结点的键,再重插入到映射,而无需复制或移动元素。
mapped
mapped_type& mapped() const; |
(仅 map 容器) | |
返回到此结点把柄所管理的容器元素对象中的 value_type
子对象的 mapped_type
成员的引用。若结点把柄为空则行为未定义。
异常
(无)
swap
void swap(/*node-handle*/& nh) noexcept(/* see below */); |
||
- 交换容器结点的所有权;
- 若一个结点为空或两个结点均为非空且
std::allocator_traits<allocator_type>::propagate_on_container_swap
为true
,则一同交换分配器。
若两个结点均为非空且 allocator_traits<allocator_type>::propagate_on_container_swap
为 false
而分配器比较不相等,则行为未定义。
异常
std::allocator_traits<allocator_type>::is_always_equal::value)
非成员函数
swap
friend void swap(/*node-handle*/& x, /*node-handle*/& y) noexcept(noexcept(x.swap(y))); |
||
等效地执行 x.swap(y) 。