在迭代时从地图(或任何其他STL容器)中删除/删除内容

26 c++ stl

据称,当迭代器变为无效时,您不能在迭代时擦除/删除容器中的元素.删除满足特定条件的元素的(安全)方法是什么?请只是stl,没有提升或tr1.

编辑 如果我想删除符合某个标准的元素,可能使用仿函数和for_each或擦除算法,是否有更优雅的方法?

Aar*_*ela 33

只要在删除迭代器后它就不会使迭代器无效:

MyContainer::iterator it = myContainer.begin();
while(it != myContainer.end())
{
    if (*it == matchingValue)
    {
       myContainer.erase(it++);
    }
    else
    {
        ++it;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1."myContainer.erase(它++);" 是微妙的 - 它在调用erase()之前正确地执行增量*,当它仍然有效时,同时将*未增加的*迭代器的(副本)传递给该函数. (16认同)
  • 重要提示:该代码适用于map,set和list,但它不适用于向量 - 从向量中删除会使迭代器无效,并使所有后续元素无效(23.2.4.3/3).现在已经放弃了我的+1,当你提到这个时,我会重新加上+1. (16认同)
  • @Ismael:函数调用是序列点,因此保证在调用擦除开始之前完成增量的副作用. (3认同)

Vik*_*ehr 10

std :: vector的示例

#include <vector>

using namespace std;

int main()
{

   typedef vector <int> int_vector;

   int_vector v(10);

   // Fill as: 0,1,2,0,1,2 etc
   for (size_t i = 0; i < v.size(); ++i){
      v[i] = i % 3;
   }

   // Remove every element where value == 1    
   for (int_vector::iterator it = v.begin(); it != v.end(); /* BLANK */){
      if (*it == 1){
         it = v.erase(it);
      } else {
         ++it;
      }
   }

}
Run Code Online (Sandbox Code Playgroud)

  • @j_random_hacker:你是正确的,它使任何迭代器无效..但是std :: vector :: erase会在擦除的(或结束)之后向元素返回一个*new*,*valid*iterator.此代码完全有效. (7认同)
  • 返回迭代器会有什么意义呢? (2认同)

mar*_*h44 9

bool IsOdd( int i )
{
    return (i&1)!=0;
}

int a[] = {1,2,3,4,5};
vector<int> v( a, a + 5 );
v.erase( remove_if( v.begin(), v.end(), bind1st( equal_to<int>(), 4 ) ), v.end() );
// v contains {1,2,3,5}
v.erase( remove_if( v.begin(), v.end(), IsOdd ), v.end() );
// v contains {2}
Run Code Online (Sandbox Code Playgroud)