我有这样的代码:
int main()
{
vector<int> res;
res.push_back(1);
vector<int>::iterator it = res.begin();
for( ; it != res.end(); it++)
{
it = res.erase(it);
//if(it == res.end())
// return 0;
}
}
一个随机访问迭代器,指向函数调用擦除的最后一个元素后面的元素的新位置,如果操作擦除了序列中的最后一个元素,则该位置为向量结尾。
这段代码崩溃了,但是如果我使用if(it == res.end())
部分,然后返回,它就可以工作了。怎么会这样?for循环缓存了res.end()
,所以不等于运算符失败了吗?
发布于 2011-01-10 18:24:25
res.erase(it)
总是返回下一个有效的迭代器,如果删除最后一个元素,它将指向.end()
在循环结束时,总是会调用++it
,因此您会递增.end()
,这是不允许的。
不过,简单地检查.end()
仍然会留下一个bug,因为您总是在每次迭代中跳过一个元素(it
通过.erase()
的返回“递增”,然后再通过循环递增)
你可能想要这样的东西:
while (it != res.end()) {
it = res.erase(it);
}
删除每个元素的步骤
(为了完整性:我假设这是一个简化的示例,如果您只想删除每个元素,而不必对其执行操作(例如,删除),则应该简单地调用res.clear()
)。
当您只有条件地擦除元素时,您可能需要类似这样的东西
for ( ; it != res.end(); ) {
if (condition) {
it = res.erase(it);
} else {
++it;
}
}
发布于 2011-01-10 18:27:52
for( ; it != res.end();)
{
it = res.erase(it);
}
或者,更一般地说:
for( ; it != res.end();)
{
if (smth)
it = res.erase(it);
else
++it;
}
发布于 2018-07-29 10:01:32
因为向量中的erase方法返回所传递迭代器的下一个迭代器。
我将举例说明如何在迭代时删除向量中的元素。
void test_del_vector(){
std::vector<int> vecInt{0, 1, 2, 3, 4, 5};
//method 1
for(auto it = vecInt.begin();it != vecInt.end();){
if(*it % 2){// remove all the odds
it = vecInt.erase(it); // note it will = next(it) after erase
} else{
++it;
}
}
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
// recreate vecInt, and use method 2
vecInt = {0, 1, 2, 3, 4, 5};
//method 2
for(auto it=std::begin(vecInt);it!=std::end(vecInt);){
if (*it % 2){
it = vecInt.erase(it);
}else{
++it;
}
}
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
// recreate vecInt, and use method 3
vecInt = {0, 1, 2, 3, 4, 5};
//method 3
vecInt.erase(std::remove_if(vecInt.begin(), vecInt.end(),
[](const int a){return a % 2;}),
vecInt.end());
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
}
输出aw如下:
024
024
024
一种更具生成性的方法:
template<class Container, class F>
void erase_where(Container& c, F&& f)
{
c.erase(std::remove_if(c.begin(), c.end(),std::forward<F>(f)),
c.end());
}
void test_del_vector(){
std::vector<int> vecInt{0, 1, 2, 3, 4, 5};
//method 4
auto is_odd = [](int x){return x % 2;};
erase_where(vecInt, is_odd);
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
}
https://stackoverflow.com/questions/4645705
复制相似问题