首页 > 解决方案 > std::map 可以移动包含的元素吗?

问题描述

我想使用指向存储在 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 可以包含不可复制和不可移动的类型,但是我想确定这不是对这种类型的某种预期适应。

标签: c++stl

解决方案


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

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

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

显示的代码使用[]运算符来修改映射,它是根据以下内容指定的try_emplace()

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

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

效果:相当于:

return try_emplace(x).first->second;

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

26.2.6 关联容器 [associative.reqmts]

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

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


推荐阅读