【问题标题】:Can std::map move contained elements?std::map 可以移动包含的元素吗?
【发布时间】:2020-02-07 01:34:05
【问题描述】:

我想使用指向存储在 std::map 中的资源的指针作为资源的句柄,但为了使其正常工作,std::map 由于从地图中插入/删除而无法移动其包含的任何元素。例如:

class Resource { ... }
std::map<std::string, Resource> resources;

resources["one"] = Resource( ... );
Resource *handle = &resources["one"];

resources["two"] = Resource( ... );
handle->doSomething(); // Is handle guaranteed to still point to the same resource?

我找不到任何说明元素是否可以移动的文档,std::map 可以包含不可复制和不可移动的类型,但是我想确定这不是对这种类型的某种预期适应。

【问题讨论】:

  • 我猜invalidates an iterator 会使指针失效,但这只是一个猜测。
  • this answer
  • AFAIK std::map 存储节点句柄而不是直接存储元素。插入新元素不应更改元素本身的实际位置,但可能会使对任何节点句柄的引用无效。不过,请带着一粒盐吃这个

标签: c++ stl


【解决方案1】:

根据 C++ 标准:std::map 是一个关联容器:

类模板地图概览[map.overview]

地图是支持唯一键的关联容器...

显示的代码使用[]操作符修改映射,用try_emplace()表示:

26.4.4.3 地图元素访问[map.access]

T&amp; operator[](const key_type&amp; x);

效果:相当于:

return try_emplace(x).first-&gt;second;

所有关联容器的要求之一是插入成员和 emplace 成员都不会使任何现有的迭代器和对容器的引用无效,而擦除只会使受影响的元素:

26.2.6 关联容器 [associative.reqmts]

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

换句话说,您的handle 仍然有效,并且不受对同一地图的任何其他更改的影响。只有从地图容器中实际删除才会使任何引用或指针失效,并且只会使容器中受擦除影响的元素失效。

【讨论】:

    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多