我什么时候使用node_type和std :: map :: insert?

时间:2016-09-10 05:54:53

标签: c++ stl iterator containers c++17

我已经习惯了std::map的现有界面 插入元素返回描述成功插入的bool,
以及插入元素的位置的迭代器。

template< class P >
std::pair<iterator,bool> insert( P&& value ); //(since C++11)

C ++ 17添加了看起来类似的调用,但具有不同的类型名称:

insert_return_type insert(node_type&& nh);   //(since C++17)

我尝试查找node_type是什么,但主要是未指定的:

template</*unspecified*/>
class /*unspecified*/

为什么在C ++ 17中添加了此功能,何时将其用于较旧的通话?

2 个答案:

答案 0 :(得分:8)

不只是std::map,所有关联和无序关联容器都添加了类似的功能。它们在[container.node]/1

的标准中有解释
  

节点句柄是一个对象,它接受来自关联容器(23.2.4)或无序关联容器(23.2.5)的单个元素的所有权。它可用于将所有权转移到另一个容器   与兼容节点。具有兼容节点的容器具有相同的节点句柄类型。 ...

上面的表格显示了具有兼容节点的容器。

节点句柄界面允许您执行的操作是将元素(节点)从一个容器传输到另一个容器(兼容),而无需复制/移动元素。相反,容器维护的各个内部节点作为一个整体进行传输。

在处理包含不可复制,不可移动类型的容器时,这是必要的。

答案 1 :(得分:6)

您可以使用extract()功能从std::map获取节点。然后,您可以将该节点放入另一个地图(或在更改其密钥后放入相同的地图中)。

node_type extract(const_iterator position); (1)   (since C++17)
node_type extract(const key_type& x);       (2)   (since C++17)
     

1)取消链接包含position所指向元素的节点   并返回拥有它的节点句柄
  2)如果容器有   密钥等效于x的元素,取消链接包含的节点   容器中的该元素并返回拥有的节点句柄   它。否则,返回一个空节点句柄。

     

在任何一种情况下,都不会复制或移动任何元素,只会复制内部元素   重新定位容器节点的指针(可能会发生重新平衡,   与erase()一样)提取节点使迭代器无效   提取元素。指针和对提取元素的引用   保持有效,但在元素归节点所有时不能使用   handle:如果元素插入到,则它们可以使用   容器

     

示例:

map<int, string> m{{1,”mango”}, {2,”papaya”}, {3,”guava”}};
auto nh = m.extract(2);
nh.key() = 4;
m.insert(move(nh));
// m == {{1,”mango”}, {3,”guava”}, {4,”papaya”}}