【问题标题】:Can a std::map rebalance during the invocation of a const function?在调用 const 函数期间,std::map 可以重新平衡吗?
【发布时间】:2014-11-11 14:40:53
【问题描述】:

我有一个const std::map<std::string, std::vector<double>> 成员变量和一个函数const std::vector* foo()。我希望这个函数有时会返回一个指向该地图元素的指针。但我担心地图可能会重新平衡 - 即使在标记为 conststd::map 函数期间 - 所以会使我返回的指针无效。我知道以后对地图的任何修改都会使我的指针失效,但这不会发生,因为我已经标记了成员变量const

我无法返回引用,因为 foo 需要返回 nullptr

我所做的安全吗?

【问题讨论】:

  • 如果 map 对象本身是 const 的,那么初始化后什么会导致它重新平衡?
  • 只有被擦除元素的迭代器才会失效(map),插入不会影响当前的迭代器;因此即使它确实重新平衡(但它是const,所以我不确定它是否能做到这一点),迭代器仍然有效。
  • @NeilKirk:这基本上就是他要问的!

标签: c++


【解决方案1】:

标准很明确:唯一可以无效的东西 一个迭代器或一个指向映射的指针或引用正在删除 它指向的元素。您甚至可以插入其他元素 在不使您的指针无效的情况下。见§23.2.4/9:

insert 和 emplace 成员不影响 迭代器和对容器的引用,擦除成员应 仅使迭代器和对已擦除元素的引用无效。

【讨论】:

    【解决方案2】:

    幸运的是,C++11 标准明确了这一点:

    §23.2.2/1:

    为了避免数据竞争 (17.6.5.9),实现应 将以下函数视为 const:begin、end、rbegin、 撕裂,前,后,数据,查找,下界,上界,相等范围, 在并且,除了在关联或无序关联容器中, 运算符[]。

    所以你是安全的。调用 const 函数时,map 无法重新平衡。

    【讨论】:

    • 这与重新平衡有什么关系,或者迭代器的有效性或指向映射的指针。
    【解决方案3】:

    我假设你的意思是“const std::vector* foo()”。

    这里不涉及再平衡。答案是,只要它指向的项目保留在 std::map 中(并且地图没有被破坏或移动),您返回的指针就不会失效。

    请注意,std::map(无论如何你都不应该使用它 - 请参阅 Chandler 在 CppCon 2014 上的演讲:http://youtu.be/fHNmRkzxHWs)一旦将项目添加到容器中,就永远不会移动它们,即使在重新平衡时也是如此。只要该项目在容器中,地图中项目的地址就会相同。不考虑重新平衡或添加和/或删除其他项目,这是正确的。

    【讨论】:

      猜你喜欢
      • 2015-07-18
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      相关资源
      最近更新 更多