【问题标题】:is the behavior for changing a hashmap as we iterate over it, defined?是否定义了在我们迭代它时更改哈希图的行为?
【发布时间】:2014-02-28 17:50:18
【问题描述】:

在使用 STL 的 C++ 中可以在迭代哈希图时更改它吗?

显然,您可以更改迭代器变量本身(iter->first 和 iter->second),但是您可以:

  1. 更改迭代器不一定指向的现有键的值?

  2. 添加新密钥?

【问题讨论】:

  • hashmap = unordered_map
  • 您不能更改 C++ 集合或映射中现有键的值。
  • “很明显,你可以改变迭代器变量本身(iter->first 和 iter->second)” -- 你测试了吗?

标签: c++ stl


【解决方案1】:

引用cppreference's docs on std::unordered_map::operator[]:

如果发生插入并导致容器重新散列,则所有迭代器都将失效。否则迭代器不受影响。引用不会失效。

因此更改与现有键关联的值是可以的,因为不会发生插入。使用insert 显式插入或通过operator[] 访问新密钥是不行的,因为它可能导致重新散列并使所有迭代器无效。

显然,您可以更改迭代器变量本身(iter->first 和 iter->second)

这只是部分正确。您可以更改值,但不能更改密钥 (iter->first)。这是因为unordered_map<K,V>::value_type = pair<const K, V>

【讨论】:

  • 恐怕我不跟。 “所以更改现有的键是可以的,因为没有发生插入。” 如果现有的键是const(你稍后会写),你如何更改它?
  • @Ali:可能我们这里有误会。通过“更改键”,我的意思是“更改与键关联的值”。我的最后一句话是对您声称可以在迭代 unordered_map 时修改 iter->first 的回应,这是不可能的
【解决方案2】:

来自this insert reference`

如果由于插入而发生重新散列,则所有迭代器都将失效。否则迭代器不受影响。

还有:

仅当新元素数等于或大于 max_load_factor()*bucket_count() 时才会发生重新散列

所以在某些情况下插入新项目是安全的,而在其他情况下则不是。除非您确定您的案例是安全的,否则最好将所有插入都视为不安全。

另一方面:

引用不会失效

因此,如果您引用了一对地图,它仍然可以安全使用。

由于它只是重新散列可以使迭代器无效的键,因此更改任何数据都不会导致任何问题。

【讨论】:

    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 2022-01-16
    • 2012-12-27
    • 2023-04-07
    • 2019-11-27
    相关资源
    最近更新 更多