先来看一段代码:
#include <vector>
using namespace std;
int main()
{
vector<int> v_list;
vector<int>::iterator it;
v_list.push_back(1);
v_list.push_back(2);
v_list.push_back(3);
for (it=v_list.begin();it!=v_list.end();++it)
{
if (*it=2)
v_list.erase(it);
}
return 0;
}
这是一段vector容器的使用代码。代码很简单,看上去也没有什么问题,但是运行后会崩溃,提示:
出现错误的时候,不要慌,不要急着关闭错误提示。来看看错误提示是什么意思。
Expression:vector iterator not incrementable
表达式:vector容器的迭代器不能递增。
我们在循环里使用了迭代器来遍历容器,当找到了元素值为2时将其删除。这个应用非常常见。删除了元素之后,就发生了错误。
在删除之前,it迭代器是按照一个顺序来遍历vector的。然而当一个元素被删除后,这种顺序就被打乱了。也就导致迭代器递增出了问题。我们原先的递增是按照未删除之前的顺序来遍历的,现在我们删除了元素,自然要重新遍历了。所以,此时你让循环继续往后走,也就是还是按照之前的顺序遍历,自然就不合理了。所以,在删除了元素之后,我们就需要重新遍历容器了。
所以,我们在删除之后,重新用容器的开始元素来给迭代器赋值,重新遍历。所以代码修改如下:
#include <vector>
using namespace std;
int main()
{
vector<int> v_list;
vector<int>::iterator it;
v_list.push_back(1);
v_list.push_back(2);
v_list.push_back(3);
for (it=v_list.begin();it!=v_list.end();)
{
if (*it==2)
{
v_list.erase(it);
it = v_list.begin();
continue;
}
++it;//不要放在for最后递增,否则continue后会递增一次而跳过新的开头
}
return 0;
}
continue执行之后,会执行for循环里面最后一个表达式,如果迭代器在里面自增,则会导致后续的迭代器值会跳过第一个元素,所以才把迭代器自增放在你看到的这个位置。
当然,如果你再深入一点,所谓的元素顺序,其实并不完全准确,更应该是迭代器对容器的遍历顺序。这里我们只是展示这样一个示例,使用时注意就行了。如果有兴趣,可以更加深入的学习STL。