std::remove_if - lambda, not removing anything from the collection

两盒软妹~` 提交于 2019-11-29 00:54:38

You need to call erase on the iterator returned from remove_if, It should look something like this:

auto new_end = std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
                              [](const DisplayDevice3d& device)
                              { return device.Modes.size() == 0; });

MyDisplayDevices.erase(new_end, MyDisplayDevices.end());
Asha

remove_if doesn't remove anything from list it just moves them to end. You need to use it along with erase. See this question for more details.

remove_if doesn't perform resizing, but instead it just returns the iterator to the element that follows the last element not removed. This iterator can be passed to erase() to do the clean up.

As others have mentioned, there are ways to make it work. However my advice would be to completely avoid remove_if and stick to a standard iterator-based removal instead. The idiom below works both for list and vector and does not produce unexpected behavior.

for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
  if( iter->shouldRemove )
    iter = vec.erase( iter ) ; // advances iter
  else
    ++iter ; // don't remove

As the comments below mention, this method does have a higher cost than remove_if when more than 1 element is removed.

remove_if works by copying elements from further ahead in the vector, and overwriting vectors that should be removed from the vector by the one immediately in front of it. For example: remove_if called on a vector to remove all 0 elements:

0 1 1 0 1 0

results in:

1 1 1 0 1 0

Notice how the vector isn't correct yet. That is because remove_if returns an iterator to the last valid element... it doesn't automatically resize the vector. You still need to call v.erase() on the iterator returned from your call to remove_if.

An example is below

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

void print( vector<int> &v )
{
  for( int i : v )
    printf( "%d ", i );
  puts("");
}

int main()
{
  vector<int> v = { 0, 1, 1, 0, 1, 0 };
  print( v ); // 0 1 1 0 1 0
  vector<int>::iterator it = remove_if( v.begin(), v.end(), [](int i){ return i == 0; } );
  print( v ); // 1 1 1 0 1 0
  v.erase( it, v.end() ); // actually cut out values not wanted in vector
  print( v ); // 1 1 1 (correct)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!