Стирание итератора Unordered_mutlimap

У меня есть следующий код

      #include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    unordered_multimap<int, int> uomap;
    typedef unordered_multimap<int, int>::iterator iter;

    uomap.insert({ 2, 30 });
    uomap.insert({ 1, 40 });
    uomap.insert({ 3, 60 });
    uomap.insert({ 2, 20 });
    uomap.insert({ 5, 50 });

    for (auto iter = uomap.begin(); iter != uomap.end(); iter++)
        cout << iter->first << " " << iter->second << "\n";
    cout << "\n";

    int k = 0;
    for (auto iter = uomap.begin(); iter != uomap.end(); iter++)
    {
        if (k % 2 == 0)
        auto it = uomap.find(it);
        uomap.erase(it);
        k++;
    }
    
    /*
    auto it1 = uomap.find(2);
    uomap.erase(it1);
    */

    for (auto iter = uomap.begin(); iter != uomap.end(); iter++)
        cout << iter->first << " " << iter->second << "\n";
    cout << "\n";

    return 0;
}

И моя проблема будет в строке 26, где у меня проблема с компиляцией. В соответствии с идентификатором VisualStudio «это» не определено, но если бы я написал то же самое за пределами «для», как в разделе с комментариями, код работал бы нормально.

В основном я тестирую различные способы получения элементов из unordered_multimap для другой проблемы, которая у меня есть, но я просто не могу заставить что-то работать. Кто-нибудь может просветить меня? Огромное спасибо.

2 ответа

Удаление всех четных элементов изunordered_map

      for (auto it = uomap.begin(); it != uomap.end(); )
{
    if (it->first % 2 == 0)
        it = uomap.erase(it);
    else
        ++it;
}

Это стандартный метод, ключевая часть которого заключается в том, что вы не увеличиваете итератор, когда выполняете стирание, вместо этого возвращаемое значение является новым значением итератора. Это связано с тем, что стирание элемента с карты также делает недействительным любой итератор, указывающий на этот элемент. Любая операция с недействительным итератором вызывает неопределенное поведение, даже просто увеличивая его. Удобно, хотяeraseметод возвращает следующий итератор.

В качестве альтернативы ответу Джона стирание элементов с четным ключом с использованием С++20

      auto is_even = [](auto keyval) { return keyval.first % 2 == 0; };
std::erase_if(uomap, is_even);
Другие вопросы по тегам