我有一个地图,其中的元素是向量。我必须从这些向量中删除所有等于特殊数字的元素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;
}
}
代码会导致运行时出现。在VS - vector iterators incompatible
中。
有人能说出原因是什么吗?
由于
答案 0 :(得分:6)
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;
}
}
但是在迭代器循环内部进行擦除是不受欢迎的,因为它使旧迭代器无效,如果你没有计划它们,可能会导致很多问题。
答案 1 :(得分: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.
答案 2 :(得分:1)
在迭代它时,你不能轻易地擦除集合中的项目。稍微考虑一下,删除itVec
“指向”的内容,删除后itVec
不再“指向”某个元素,因此它不再具有“下一个”指针。
如果你检查,例如this reference,您将看到erase
函数返回下一个元素的迭代器。用这个继续循环(当然不增加它)。
答案 3 :(得分:1)
考虑使用与vector
不同的集合类,或者创建一个删除了所需项目的新向量,而不是从现有向量中删除。