命名空间
变体
操作

节点句柄 (C++17)

来自 cppreference.com
< cpp‎ | 容器
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_mapstd::set 中。

节点句柄可能是空的,在这种情况下,它不包含任何元素也不包含任何分配器。默认构造和已移动的节点句柄为空。此外,可以通过对容器成员函数 extract 的失败调用来生成空节点句柄。

在元素由节点句柄拥有时获得的指向元素的指针和引用在元素成功插入容器时将失效。

对于所有 key_typeKmapped_typeT 的映射容器(std::map, std::multimap, std::unordered_mapstd::unordered_multimap),如果 std::pair 的用户定义特化存在于 std::pair<K, T>std::pair<const K, T> 中,涉及节点句柄的操作的行为是未定义的。

内容

[编辑] 成员类型

类型 定义
key_type (仅映射容器) 节点中存储的键[编辑]
mapped_type (仅映射容器) 存储在节点中的元素的映射部分[编辑]
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)
1) 默认构造函数将节点句柄初始化为空状态。
2) 移动构造函数从 nh 中获取容器元素的所有权,移动构造成员分配器,并将 nh 留在空状态。

参数

nh - 具有相同类型(不一定是相同容器)的节点句柄

备注

节点句柄是仅限移动的,未定义复制构造函数。

operator=

/*node-handle*/& operator=(/*node-handle*/&& nh);
  • 如果节点句柄不为空,则
  • 通过调用 ator_traits::destroy 销毁由该节点句柄管理的容器元素对象中的 value_type 子对象;
  • 通过调用 ator_traits::rebind_traits</*container-node-type*/>::deallocate 释放容器元素。
  • nh 获取容器元素的所有权。
  • 如果节点句柄为空(因此不包含分配器)或如果 ator_traits::propagate_on_container_move_assignmenttrue,则将分配器从 nh 移动赋值。
  • nh 设置为空状态。

如果节点不为空且 ator_traits::propagate_on_container_move_assignmentfalse 且分配器不相同,则行为未定义。

参数

nh - 具有相同类型(不一定是相同的容器)的节点句柄

返回值

*this

异常

不抛出任何异常。

备注

节点句柄是移动唯一的,未定义复制赋值。

析构函数

~/*node-handle*/();
  • 如果节点句柄不为空,则
  • 通过调用 ator_traits::destroy 销毁此节点句柄管理的容器元素对象中的 value_type 子对象。
  • 通过调用 ator_traits::rebind_traits</*container-node-type*/>::deallocate 释放容器元素。

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 成员的非常量引用。如果节点句柄为空,则行为未定义。

异常

不抛出任何异常。

备注

此函数使修改从映射中提取的节点的键成为可能,然后将其重新插入映射,而无需复制或移动元素。

mapped

mapped_type& mapped() const;
(仅限映射容器)

返回此节点句柄管理的容器元素对象中的 value_type 子对象的 mapped_type 成员的引用。如果节点句柄为空,则行为未定义。

异常

不抛出任何异常。

swap

void swap(/*node-handle*/& nh) noexcept(/* see below */);
  • 交换容器节点的所有权;
  • 如果一个节点为空,或者如果两个节点都不为空且 ator_traits::propagate_on_container_swaptrue,则也交换分配器。

如果两个节点都不为空且 ator_traits::propagate_on_container_swapfalse 且分配器不相同,则行为未定义。

异常

noexcept 规范:  
noexcept(ator_traits::propagate_on_container_swap::value ||
         ator_traits::is_always_equal::value)

[edit] 非成员函数

swap

friend void swap(/*node-handle*/& x, /*node-handle*/& y) noexcept(noexcept(x.swap(y)));

有效地执行 x.swap(y)

此函数对普通的 非限定限定查找不可见,并且只能通过 依赖于参数的查找node-handle 是参数的关联类时找到。