C++:从映射中删除迭代器,然后递增到下一个迭代器

C++: Erasing an iterator from a map and then incrementing to the next iterator

本文关键字:迭代器 然后 下一个 C++ 映射 删除      更新时间:2023-10-16

此方法会导致中止错误:"map/set iterator not incrementable."因此,在if失败并且确定了应该擦除的有效迭代器之后(并且是),通过++_iter继续到映射中的下一个迭代器失败,因为_iter不再是有效的对象/指针。

迭代地图并能够删除整个地图中的单个项目的正确程序是什么?

typedef std::map<std::string, BITMAP*> MapStrBmp;
typedef MapStrBmp::iterator MapStrBmpIter;
\...
void BitmapCache::CleanCache() {
    //Clean the cache of any NULL bitmaps that were deleted by caller.
    for(MapStrBmpIter _iter = _cache.begin(); _iter != _cache.end(); ++_iter) {
        if(_iter->second != NULL) {
            if((_iter->second->w < 0 && _iter->second->h < 0) == false) continue;
        }
        _cache.erase(_iter);
    }
}

您只需要稍微小心一点:

void BitmapCache::CleanCache() {
    //Clean the cache of any NULL bitmaps that were deleted by caller.
    for(MapStrBmpIter _iter = _cache.begin(); _iter != _cache.end(); ) {
        if(_iter->second != NULL) {
            if((_iter->second->w < 0 && _iter->second->h < 0) == false)
            {
                ++_iter;
                continue;
            }
        }
        _cache.erase(_iter++);
    }
}

map::erase(iterator)为您提供了一个迭代器,指向擦除后映射中的下一个元素(如果有的话)。因此,你可以做:

for(MapStrBmpIter _iter = _cache.begin(); _iter != _cache.end(); ) {
    if(_iter->second != NULL) {
        if((_iter->second->w < 0 && _iter->second->h < 0) == false) {
           ++_iter;
           continue;
        }
    }
    _iter = _cache.erase(_iter);
}

关联容器的标准擦除循环:

for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
    if (delete_condition)
    {
        m.erase(it++);
    }
    else
    {
        ++it;
    }
}

在迭代过程中安全擦除迭代器的规范方法是使用container::erase:的结果

void BitmapCache::CleanCache() {
    //Clean the cache of any NULL bitmaps that were deleted by caller.
    MapStrBmpIter _iter = _cache.begin();
    while (_iter != _cache.end()) {
        bool erase_entry= true;
        if(_iter->second != NULL) {
            if((_iter->second->w < 0 && _iter->second->h < 0) == false) 
                erase_entry= false;
        }
        if (erase_entry)
            _iter= _cache.erase(_iter);
        else
            ++_iter;
    }
}