Как безопасно "всплывать" из std :: map без лишнего копирования? - PullRequest
2 голосов
/ 06 августа 2020

У меня есть объект std::map.

std::map<std::string, std::string> m;

m.insert({ "abcd", "foo" });
m.insert({ "1234", "bar" });

, и я хочу получить и удалить первый элемент, например:

auto iter = m.begin();
auto [key, value] = std::move(*iter);
m.erase(iter);
do_something_with(key, value);

Считается ли это безопасным? (Переход от итератора должен сделать ключ пустой строкой, что сделает m недопустимой картой.)

Ответы [ 3 ]

2 голосов
/ 06 августа 2020

Вы можете использовать std::map::extract следующим образом:

auto nh = m.extract(m.begin());

, а затем использовать ключ и значение следующим образом:

do_something(nh.key(), nh.mapped());

Это имеет необходимое свойство, что лишние копии не делаются.

2 голосов
/ 06 августа 2020

Считается ли это безопасным?

При условии, что карта не пуста, да.

Однако , обратите внимание, что ключ будет глубокой копией; не двинулся один. Это связано с тем, что ключ элемента карты - const.

Как безопасно «всплывать» из std :: map без дополнительной копии?

Это возможно также перейти от ключа, если вы используете функцию-член extract:

auto handle = m.extract(m.begin());
// if you need separate objects:
auto key = std::move(handle.key());
auto mapped = std::move(handle.mapped());
1 голос
/ 06 августа 2020

Использовать извлечение стандартной карты. Используя полученный дескриптор узла, переместите ключ / значение в переменные типа ключ / значение.

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

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