2

我想从向量中删除一些迭代器,所以这就是我现在所拥有的。

void function(std::vector <class*> & vector)
{
    std::vector <class*>::iterator it;
    for(it = vector.begin(); iter != vector.end(); ++iter)
        {
            if(it->value == 1)
                vector.erase(it);
        }
    Display(vector);
    return;
}

显然,当迭代器被删除是向量中的最后一个时,这段代码给了我一个错误,否则它似乎工作正常。我知道在这样的循环中修改向量可能不是可取的行为,但如果我必须这样做,最好的方法是什么?

谢谢。

4

3 回答 3

5
for (it = vector.begin(); it != vector.end(); )
{
    if (it->value == 1)
        it = vector.erase(it);
    else
        ++it;
}

但是对于这种情况,您实际上应该只使用std::remove_if适当的谓词。

于 2012-04-18T19:00:52.383 回答
4

另一种方法:

vector.erase( std::remove_if( vector.begin(), vector.end(), boost::bind( &class::value, _1 ) == 1 ), vector.end() );

boost::bind如果可用,可能会被替换std::bind

于 2012-04-18T19:01:06.333 回答
-1

在迭代它时从向量中擦除是个坏主意。简单过滤一下。

void function(std::vector <class*> & vector)
{
    std::vector <class*>::iterator from= vector.begin();
    std::vector <class*>::iterator to= from;
    for(; from != vector.end(); ++from)
        {
            if((*from)->value == 1) continue; 
            // it should be (*from) or use boost::ptr_vector
            *(to++)=*from;
        }
    vector.erase( to, vector.end() );
    Display(vector);
    return;
}

这与 Ylisar 的代码完全相同。恕我直言,这对于矢量来说是最好的,如果你总是要删除一些东西,但是如果删除非常罕见(对于整个一个矢量),请使用 Benjamin Lindley 版本。

无论优化是什么,您都可以仅在有要删除的内容时进行过滤:

void function(std::vector <class*> & vector)
{
   std::vector <class*>::iterator to= vector.begin(); 
   for(; to != vector.end(); ++to)
   {
      if((*to)->value == 1) 
      {
         std::vector <class*>::iterator from=to;
         for(++from; from != vector.end(); ++from)
         {
            if((*from)->value == 1) continue;
            *(to++)=*from;
         }
         vector.erase( to, vector.end() );
         break;
      }
    }
    Display(vector);
    return;
}

如果您不需要保留顺序,则可以从背面复制到最小复制过热:

void function(std::vector <class*> & vector)
{
   std::vector <class*>::iterator to= vector.begin(); 
   std::vector <class*>::iterator from=vector.end();
   if(to == from) return;
   for(;;)
   {
      if((*to)->value == 1) // need skip value from begin
      {
         for( --from; from != to; --from)
         {
            if((*from)->value == 1) continue; // need skip value from end
            *to=*from;
            ++to; // copied, move to next
         }
      } 
      else 
      {
         ++to; //preserved, move to next
      }
      if(to == from) 
      {
         vector.erase( to, vector.end() ); 
         break;
      }
    }
    Display(vector);
    return;
}
于 2012-04-18T19:14:02.873 回答