std :: unordered_map :: extract references/pointers invalidation

hae*_*lix 8 c++ unordered-map erase c++17

对于新的C++ 17 std::unordered_map::extract函数,文档说:

提取节点仅使提取的元素的迭代器无效,并保留未擦除元素的相对顺序.指针和对提取的元素的引用仍然有效,但是当元素由节点句柄拥有时不能使用它们:如果元素被插入到容器中,它们就变得可用.

当然,extract使提取的迭代器无效(这是容器的一个东西,从中移除了元素).但是关于引用和指针的文档很时髦 - 它说它们仍然有效但在重新插入(可能是另一个)容器之前不能使用 - 它们将保留它们的值(?).

问题:我的用例是在提取后检查一个元素,即仅使用一个哈希查找执行erase-examine-discardForGood操作.该extract功能似乎非常适合这一点,但文档建议我不能node_type用来检查元素.我的理解是否正确?

cpp*_*ner 7

您可以认为extract(以及相应的insert)“神奇地”更改了受影响的地图元素的类型:当该元素由地图拥有时,它具有类型std::pair<const key_type, mapped_type>,但是当该元素由节点句柄拥有时,它具有类型std::pair<key_type, mapped_type>(因此您可以改变键的值)。

因此,如果在元素归映射所有时获取该元素的引用/指针,则在提取该元素之后和重新插入该元素之前不能使用该引用/指针,否则将违反严格的别名规则。

然而,使用提取后获取的引用/指针是完全可以的。


Lig*_*ica 6

是的,这就是文字所说的.

乍一看,这似乎是一个相当随意的限制,虽然我确信它有一些好的,如果是神秘的原因.

话虽这么说,句柄本身具有成员函数value()/ key()/ mapped()可能对你有价值(!).

节点句柄是一种只移动类型,它拥有并提供对存储在节点中的元素(value_type)的访问,并提供对元素的关键部分(key_type)和元素的映射部分的非const访问( mapped_type).(参考)

  • @haelix有一些hanky-panky在引擎盖下将`pair <const Key,Value>`变成`pair <Key,Value>`(没有移动或复制).由实现来确保它的工作原理,但不能保证这种魔法是可移植的.当打字出现时,语言律师会变得相当兴奋.需要担心编译器优化,担心缓存失效,我不记得其他所有内容.只要你比较指针,而不是解除引用你的缓存指针,我认为你已经完好无损. (2认同)