是否可以为每个循环擦除c ++ 11中std :: list的元素

Haa*_*hii 9 c++ stl c++11

我想为每个循环使用新的C++ 11迭代列表的所有元素并删除某些元素.例如

std::list<int> myList;
myList.push_back(1); 
myList.push_back(13);
myList.push_back(9);
myList.push_back(4);

for(int element : myList) {
    if(element > 5) {
        //Do something with the element

        //erase the element
    }else{
        //Do something else with the element
    }
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用for循环执行此操作,还是必须返回迭代器才能实现此目的?

Kar*_*k T 6

你应该能够做到这一点

myList.erase(std::remove_if(myList.begin(), myList.end(),
    [](int& element) 
    { 
        return element > 5;
    } 
    ),myList.end());
Run Code Online (Sandbox Code Playgroud)

或简单(由本杰明林德利提供)

myList.remove_if(
    [](int& element) 
    { 
        return element > 5;
    } 
    );
Run Code Online (Sandbox Code Playgroud)

  • @fish:`std :: remove_if`不会删除元素,它会移动或交换它们(也就是移位). (4认同)
  • 切换元素对于列表来说效率很低 (2认同)
  • @ Cheersandhth.-Alf我相信你错了,删除和插入是std :: list的O(1).对于顺序容器(例如std :: vector),将发生移位. (2认同)

Ste*_*sop 5

您不能在基于范围的for循环中擦除标准容器的元素 - 循环本身具有您当前正在访问的元素的迭代器,并且擦除它会在循环递增之前使该迭代器无效.

基于范围的for在标准的6.5.4中定义为等效(略微简化):

for (auto __begin=begin-expr, __end=end-expr; __begin != __end; ++__begin) {
    for-range-declaration = *__begin;
    statement
}
Run Code Online (Sandbox Code Playgroud)

begin-exprend-expr拥有自己的冗长的定义,但在你的例子他们myList.begin()myList.end()分别.