对于新的C ++ 17 std::unordered_map::extract
函数,文档显示:
提取节点仅会使提取的迭代器无效 元素,并保留非元素的相对顺序 已删除。指向提取元素的指针和引用仍然有效, 但是当element由节点句柄拥有时不能使用:它们 如果将元素插入到容器中,则变得可用。
自然,extract
使提取的迭代器(这是从中删除元素的容器之物)的迭代器无效。但是该文档对引用和指针很时髦-它表示这些引用和指针仍然有效,但在重新插入(可能是另一个)容器之前不能使用-在这种情况下它们将保留其值(?)。
问题:我的用例是在提取后检查元素,即仅执行一次哈希查找就执行了一次delete-examine-discardForGood操作。 extract
函数似乎非常适合此功能,但是文档显示我不能使用node_type
来检查元素。我的理解正确吗?
答案 0 :(得分:6)
是的,这就是文字所说的。
乍看之下,这似乎是一个相当随意的限制,尽管我敢肯定有一定的理由(如果是奥秘的话)。
也就是说,句柄本身具有成员函数value()
/ key()
/ mapped()
,对您来说可能是有价值的(!)。
节点句柄是仅移动类型,它拥有并提供对存储在节点中的元素(value_type)的访问,并提供对元素的关键部分(key_type)和映射对象的非常量访问元素(mapped_type)。 (ref)
答案 1 :(得分:4)
您可以认为extract
(以及相应的insert
)“神奇地”改变了受影响的地图元素的类型:当该元素归地图所有时,其类型为std::pair<const key_type, mapped_type>
,但是当元素由节点句柄拥有时,其类型为std::pair<key_type, mapped_type>
(因此您可以更改键的值)。
因此,如果您在地图拥有该元素时获取了该元素的引用/指针,则在提取元素之后并重新插入元素之前,您将无法使用该引用/指针,否则违反严格的别名规则。
但是,完全可以使用提取后获取的参考/指针。