当心使用std::map erase()

std::map在过去的旧的实现中,map::erase()的返回值类型为void,在遍历过程当中,若是要erase,要格外当心,由于iter会在某些状况下失效。ide

    std::map<int, int> mapTest;
    mapTest.insert(std::make_pair(1, 1));
    mapTest.insert(std::make_pair(2, 2));
    mapTest.insert(std::make_pair(3, 3));
    mapTest.insert(std::make_pair(4, 4));
    mapTest.insert(std::make_pair(5, 5));
    
    // Wrong! to erase the last iter    
    std::map<int, int>::iterator iter = mapTest.begin();
    for(; iter != mapTest.end(); ++iter)
    {
        int key = iter->first;
        printf("%d\t", key);
        if(key == 5)
        {
            mapTest.erase(iter);
        }
    }
    // Wrong:
    std::map<int, int>::iterator iter = mapTest.begin();
    for(; iter != mapTest.end(); )
    {
        int key = iter->first;
        printf("%d\t", key);
        if(key == 5)
        {
            std::map<int, int>::iterator iterTmp = iter;            
            mapTest.erase(iterTmp);
            ++iter;
            continue;
        }
        ++iter;
    }
    // Correct:
    std::map<int, int>::iterator iter = mapTest.begin();
    for(; iter != mapTest.end(); )
    {
        int key = iter->first;
        printf("%d\t", key);
        if(key == 5)
        {
            std::map<int, int>::iterator iterTmp = iter;
            ++iter;
            mapTest.erase(iterTmp);
            continue;
        }
        ++iter;
    }
    // Correct
    std::map<int, int>::iterator iter = mapTest.begin();
    for(; iter != mapTest.end(); )
    {
        int key = iter->first;
        printf("%d\t", key);
        if(key == 5)
        {
            mapTest.erase(iter++);
            continue;
        }
        ++iter;
    }

在新版的实现中,std::map::erase返回值类型为std::map::iterator,返回下一个iterator,那咱们在以上的状况中,就能够写成:it

    std::map<int, int>::iterator iter = mapTest.begin();
    for(; iter != mapTest.end(); )
    {
        int key = iter->first;
        printf("%d\t", key);
        if(key == 5)
        {
            iter = mapTest.erase(iter);
            continue;
        }
        ++iter;
    }