我想使用指向存储在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 ++标准:std::map
是关联容器:
类模板地图概述[map.overview]
地图是支持唯一键的关联容器...
所示的代码使用[]
运算符来修改根据try_emplace()
指定的地图:
26.4.4.3地图元素访问[map.access]
T& operator[](const key_type& x);
效果:等效于:
return try_emplace(x).first->second;
[[[all关联容器的要求之一是,插入或emplace成员均不会使容器的任何现有迭代器和引用无效,而擦除只会使受影响的元素无效:
26.2.6关联容器[associative.reqmts]insert和emplace成员不得影响容器的迭代器和引用,以及擦除成员仅使迭代器和对已删除元素的引用无效。
换句话说,您的handle
仍然有效,并且不受同一地图其他任何更改的影响。仅从映射容器中进行实际删除会使所有引用或指针无效,并且仅使容器中受擦除影响的元素无效。