c++ - 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++ 标准: 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
仍然有效,并且不受对同一地图的任何其他更改的影响。只有从映射容器中实际删除才会使任何引用或指针无效,并且只会使容器中受擦除影响的元素无效。
推荐阅读
- python - 计数到第一列并总结到其余列 pandas groupby
- eclipse - 使用 Subclipse 插件
- keras - Google AI Platform 上的所有超调试验都失败了
- xcode - 旧 iOS 版本中 Xcode 模拟器屏幕出错
- javascript - JS Keydown 在第一个事件之后触发事件之前有一些奇怪的 1 秒延迟
- javascript - 如何存储谷歌浏览器扩展的按钮保存状态
- algorithm - 给定“截止日期”,二分搜索是否最优?
- maven - Maven 模块和 quarkus 编译/实时重新加载
- rust - 数据互斥带来的 Rust 生命周期问题
- python - OpenCV:比较来自网络摄像头和图像的姿势