首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >向量擦除迭代器

向量擦除迭代器
EN

Stack Overflow用户
提问于 2011-01-10 18:22:04
回答 10查看 141.9K关注 0票数 77

我有这样的代码:

代码语言:javascript
复制
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(),所以不等于运算符失败了吗?

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2011-01-10 18:24:25

res.erase(it)总是返回下一个有效的迭代器,如果删除最后一个元素,它将指向.end()

在循环结束时,总是会调用++it,因此您会递增.end(),这是不允许的。

不过,简单地检查.end()仍然会留下一个bug,因为您总是在每次迭代中跳过一个元素(it通过.erase()的返回“递增”,然后再通过循环递增)

你可能想要这样的东西:

代码语言:javascript
复制
 while (it != res.end()) {
        it = res.erase(it);    
 }

删除每个元素的步骤

(为了完整性:我假设这是一个简化的示例,如果您只想删除每个元素,而不必对其执行操作(例如,删除),则应该简单地调用res.clear())。

当您只有条件地擦除元素时,您可能需要类似这样的东西

代码语言:javascript
复制
for ( ; it != res.end(); ) {
  if (condition) {
    it = res.erase(it);
  } else {
    ++it;
  }
}
票数 157
EN

Stack Overflow用户

发布于 2011-01-10 18:27:52

代码语言:javascript
复制
for( ; it != res.end();)
{
    it = res.erase(it);
}

或者,更一般地说:

代码语言:javascript
复制
for( ; it != res.end();)
{
    if (smth)
        it = res.erase(it);
    else
        ++it;
}
票数 31
EN

Stack Overflow用户

发布于 2018-07-29 10:01:32

因为向量中的erase方法返回所传递迭代器的下一个迭代器。

我将举例说明如何在迭代时删除向量中的元素。

代码语言:javascript
复制
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如下:

代码语言:javascript
复制
024
024
024

一种更具生成性的方法:

代码语言:javascript
复制
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;    
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4645705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档