【问题标题】:Is second part of map<..,..> stable?map<..,..> 的第二部分是否稳定?
【发布时间】:2012-03-18 07:35:55
【问题描述】:

如果我们有一个 map &lt;int, vector&lt;int&gt; &gt;vectors 在地图的红黑树更改时移动,或者它存储指向 vectors 的指针或类似的东西并且不移动它们(否则使用地图将不会'不再是 O(lg n) 例如如果我们将元素 push_back 到一些 vectors)

【问题讨论】:

    标签: c++ stl map


    【解决方案1】:

    看到这个: std::map, pointer to map key value, is this possible?

    第二最佳答案:

    第 23.1.2#8 节(关联容器要求):

    “插入成员不会影响迭代器和容器引用的有效性,擦除成员只会使迭代器和被擦除元素的引用失效。”

    所以 yes 保证存储指向地图元素的数据成员的指针是有效的,除非您删除 那个 元素。

    因此,如果保留引用,则无法将数据复制到内存的不同部分。如果是这样的话,我根本看不出执行任何复制的意义......

    【讨论】:

    • 这并没有解决核心问题:std::map 是否允许移动元素?
    • 如果一个元素被移动,指向它的指针/引用将会失效(我说的是普通指针,而不是迭代器)。这就是为什么 - 不 - 不允许移动元素。 ...好吧,理论上某些实现可以将对象复制到某处,然后移回旧位置,但这有点奇怪。
    • 虽然奇​​怪的是erase没有这样的要求。
    • 请注意:文本已移至新版标准草案中的新章节 p.744, 23.2.4#9。 N3797, 2013-10-13
    【解决方案2】:

    不,向量不会四处移动。树的操作只是重新排列节点之间的指针。它们不会在内存中移动节点或其内容。

    【讨论】:

      【解决方案3】:

      我相信 C++03 不会对内存中数据的稳定性做出任何保证,这将是一个实现细节(实际上,如果不进行测试,您就不能安全地假设这一点) .

      注意迭代器到map的保存和实际向量在内存中的位置完全不同。迭代器的有效性在 C++ 规范中明确定义(无论何时有效,何时无效),但树的实际内部行为却没有。

      也就是说,任何体面的编译器(对于发布版本/启用优化)都会优化实现,以便在向量在树中移动时不实际复制向量,std::map 的 C++11 实现将使用 move语义来保证这种行为。

      你不能假设内部只有指针被移动。

      【讨论】:

      • std::map&lt;K, V&gt; 在标准的所有修订版中都必须是基于节点的容器,即未从映射中删除的节点保留在内存中:迭代器和指向映射元素的指针都不会变为在节点被擦除或地图被破坏之前无效。
      • 但它也保留了引用(普通指针),而不仅仅是迭代器。这使您可以争论内存。除非有一些奇怪的内存地址虚拟化......
      猜你喜欢
      • 2015-11-23
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-21
      相关资源
      最近更新 更多