Может ли std :: map перемещать содержащиеся элементы? - PullRequest
2 голосов
/ 07 февраля 2020

Я хотел бы использовать указатели на ресурсы, хранящиеся в 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 может содержать не копируемый и неподвижный тип, однако я хочу убедиться, что это не то, что предназначено адаптация к такому типу.

1 Ответ

2 голосов
/ 07 февраля 2020

Из стандарта C ++: a std::map - это ассоциативный контейнер:

Обзор карты шаблона класса [map.overview]

Карта - это ассоциативный контейнер, который поддерживает уникальный keys ...

В показанном коде для изменения карты используется оператор [], указанный в терминах try_emplace():

26.4.4.3 map элемент доступа [map.access]

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

Эффекты: Эквивалентно:

return try_emplace(x).first->second;

Одно из требований все ассоциативные контейнеры в том, что ни вставка, ни члены emplace не делают недействительными какие-либо существующие итераторы и ссылки на контейнер, а стирание делает недействительными только затронутые элементы:

26.2.6 Ассоциативные контейнеры [associative.reqmts]

Элементы insert и emplace не должны влиять на действительность итераторов и ссылок на контейнер, а члены стирания должны делать недействительными только итераторы и ссылки на стертые элементы .

Другими словами, ваш handle остается действительным и не подвержен никаким другим изменениям той же карты. Только фактическое удаление из контейнера карты делает недействительными любые ссылки или указатели и только на элементы в контейнере, на которые влияет удаление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...