1

我有一个元素是向量的地图。我必须从这些向量中删除所有等于特殊数字的元素num

std::map<size_t,std::vector<size_t> > myMap;
for (std::map<size_t,std::vector<size_t> >::iterator itMap = myMap.begin();itMap != myMap.end();++itMap )
{
    for (std::vector<size_t>::iterator itVec = itMap->second.begin();itVec != itMap->second.end();)
    {
        auto itNextVec = itVec;
        ++itNextVec;
        if (*itVec == num)
        {
            itMap->second.erase(itVec );
        }
        itVec = itNextVec;
    }
}

该代码导致运行时 exepssion .In VS - vector iterators incompatible。有人可以指出这是什么原因吗?

谢谢

4

4 回答 4

9

std::vector::erase返回一个iterator到列表的下一个位置,所以当你执行擦除时,你应该让你的迭代器等于返回的值。

你唯一需要考虑的是返回的iterator可能是结束,所以你应该检查一下。

我个人喜欢做的是在擦除之后,我得到下一个迭代器位置,我回到返回的迭代器的前一个位置,然后在for loop

例子:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> myInt;
    myInt.push_back(1);myInt.push_back(2);myInt.push_back(3);

    for(auto iter = myInt.begin();
        iter != myInt.end();
        ++iter)
    {
        if(*iter == 1)
        {
            iter = myInt.erase(iter);
            if(iter != myInt.begin())
            {
                iter = std::prev(iter);
                continue;
            }
        }

        std::cout << *iter << std::endl;
    }
}

但是在迭代器循环中进行擦除是不受欢迎的,因为它会使旧的迭代器无效,如果你没有计划的话,这可能会导致很多问题。

于 2013-02-23T17:01:45.207 回答
2

擦除将使迭代器无效

Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are 
invalidated, with all iterators, pointers and references to elements before position (or 
first) are guaranteed to keep referring to the same elements they were referring to 
before the call.
于 2013-02-23T16:50:47.597 回答
1

在迭代它时,您不能轻易地从集合中删除一个项目。想一想,您删除了itVec“指向”的内容,删除后itVec不再“指向”一个元素,因此它不再具有“下一个”指针。

如果您检查例如this reference,您将看到该erase函数将迭代器返回到下一个元素。继续这个循环(当然不要增加它)。

于 2013-02-23T16:50:19.340 回答
1

考虑使用不同的集合类,vector或者创建一个新的向量,删除所需的项目,而不是从现有向量中删除。

于 2013-02-23T16:53:34.763 回答