简体   繁体   English

c ++在遍历所有迭代器的同时擦除std :: vector.end()

[英]c++ erase the std::vector.end() while looping over all iterators

I want to erase some iterator from a vector, so this is what I have now. 我想从向量中删除一些迭代器,所以这就是我现在所拥有的。

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;
}

Apparently this code gives me an error when the iterator got removed is the last one in the vector, otherwise seems it's working fine. 显然,当迭代器被移除时,这个代码给了我一个错误,它是向量中的最后一个,否则看起来它工作正常。 I know it might not be desirable behavior to modify vector inside such a loop, but if I have to do this, what will be the best way? 我知道在这样的循环中修改向量可能不是理想的行为,但如果我必须这样做,那么最好的方法是什么?

Thanks. 谢谢。

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

But for this case, you should actually just use std::remove_if with an appropriate predicate. 但是对于这种情况,您实际上应该使用std::remove_if和适当的谓词。

Another approach: 另一种方法:

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

boost::bind can probably be replaced by std::bind if it's available. 如果可用的话, boost::bind可能会被std::bind取代。

It's bad idea to erase from vector while iterate over it. 在向量上迭代时从矢量中删除是个坏主意。 Simply filter it. 只需过滤它。

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;
}

This is functionality exactly identical as code by Ylisar. 这个功能与Ylisar的代码完全相同。 IMHO this is best for vector, if you always have something to remove, but if remove is very rare (for whole one vector), use Benjamin Lindley version. 恕我直言这是最好的矢量,如果你总是有东西要删除,但如果删除是非常罕见的(对于整个一个矢量),使用本杰明林德利版本。

Whatever optimization may be, you may filter only if it you have something to erase: 无论优化是什么,只有在您有要删除的内容时才可以过滤:

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;
}

If you don't need to preserve order, you may copy from back to minimal copy overheat: 如果您不需要保留订单,则可以从最小版本过热复制到最小版本过热:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM