关于vector中erase删除迭代器的问题
当你用erase以迭代器方式删除vector中的元素时,vector会自动将被删除元素后边的元素往上挪一位,所以此时指向删除元素的迭代器指向了被删除元素后面的元素,所以在循环中,此时迭代器就不应该加1了,大概像下面这种写法
for (itE = listE.begin(); itE != listE.end();) { //取出一条边 ActivityEdge* currE = *itE; if (currE->start == findV) { listE.erase(itE); } else { itE++; } }
上面的代码在dev,cfree编译器中运行没有问题,但是在vs中运行这段代码是会报错的,程序会崩溃显示vector iterators incompatible,我觉得这是vs的一个保护机制,也就是微软的老头们觉得用这个迭代器不太好,所以就禁用了。O(∩_∩)O,我觉得也是有点不好,因为这个迭代器本来是指向删除元素的,但是元素删除后,这个迭代器竟然指向了被删除元素的下一个元素,感觉这个迭代器有点不忠心,本来是要和被删除元素捆绑在一起的,但是在被删除元素没了之后,这个迭代器竟然偷偷摸摸的和别的元素有了关系,🤭,反正在vs各种版本中,上面的代码都运行不了,那么如何改正呢?,见下面
for (itE = listE.begin(); itE != listE.end();) { //取出一条边 ActivityEdge* currE = *itE; if (currE->start == findV) { itE=listE.erase(itE); } else { itE++; } }
这段代码就是利用了erase的返回值,当我们用erase删除一个元素后,erase返回的是下一个元素的迭代器,将这个返回值赋给那个原来指向被删除元素的迭代器,所以这个迭代器就名正言顺的指向了下一个元素,这比偷偷摸摸的行为好太多了。😄,严肃点说的话,感觉这就是显式的让迭代器指向了下一个元素,可能微软的老头们比较喜欢这种方式。