std::map 中对元素的引用是否可以失效?

Can a reference to an element inside an std::map be invalidated?

我有一个多线程应用程序和一个共享资源 std::map<KeyType, ElementType>。我使用互斥锁来保护插入、获取和删除。

我的 get 方法 return 是对存储元素的引用(在 return 上解锁),然后我对该元素进行了一些处理。

问题: 是否有可能在使用存储的元素引用时,另一个线程可能会更改 std::map 因此元素将被移动到不同的地址并且引用将不再有效? (我知道有某些 ADT 实现会在调整大小时重新排列 ADT)。

另一个线程可能会擦除元素或破坏地图,这当然也会使元素无效。

擦除元素只会使迭代器和对该元素的引用无效。插入不会使映射中的迭代器或引用无效。

(至少 second-hand documentation says 是这样的——如果轶事证据重要,我认为这是一个永远不会失效的假设。)

另一个问题仍然存在:通过返回的引用操作元素不是线程安全的。您需要同步,例如每个元素 - 并确保您不违反锁定层次结构。

关联容器(std::map 是)的迭代器失效规则在 [associative.reqmts]/9:

The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

因此,如果一个线程插入一个元素,它不会影响对现有元素的任何引用。但是,如果它删除了一些东西,其他线程可能会很无聊。我会说,某种形式的逐元素锁定是有序的。