std::unordered_map::extractreferences/pointers失效

std::unordered_map::extract references/pointers invalidation

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

Extracting a node invalidates only the iterators to the extracted element, and preserves the relative order of the elements that are not erased. Pointers and references to the extracted element remain valid, but cannot be used while element is owned by a node handle: they become usable if the element is inserted into a container.

自然地,extract 使提取的迭代器无效(这是容器的东西,从中删除了元素)。但是文档对引用和指针很奇怪 - 它说这些仍然有效但 不能使用 直到重新插入(可能是另一个)容器 - 在这种情况下它们将保留它们的值( ?).

问题:我的用例是在提取后检查元素,即仅使用一次哈希查找执行擦除-检查-丢弃良好操作。 extract 函数似乎非常适合这个,但是文档建议我不能使用 node_type 来检查元素。我的理解正确吗?

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

乍一看,这似乎是一个相当武断的限制,但我确信其中有一些好的(即使是神秘的)理由。

也就是说,句柄本身具有成员函数 value()/key()/mapped(),可能对您有价值 (!)。

Node handle is a move-only type that owns and provides access to the element (the value_type) stored in the node, and provides non-const access to the key part of the element (the key_type) and the mapped part of the element (the mapped_type). (ref)

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

因此,如果您在地图拥有该元素时获取该元素的 reference/pointer,则您不能在提取该元素之后和重新创建该元素之前使用该 reference/pointer -已插入,否则您将违反严格的别名规则。

不过,使用提取后得到的reference/pointer完全没问题。