Как уже упоминали другие, есть способы заставить его работать.Однако мой совет будет полностью избегать remove_if
и вместо этого придерживаться стандартного удаления на основе итераторов.Приведенная ниже идиома работает как для list
, так и vector
и не приводит к неожиданному поведению.
for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
if( iter->shouldRemove )
iter = vec.erase( iter ) ; // advances iter
else
++iter ; // don't remove
Как отмечается в комментариях ниже, этот метод стоит дороже, чем remove_if
, когда более 1элемент удаляется.
remove_if
работает, копируя элементы из вектора впереди и перезаписывая векторы, которые должны быть удалены из вектора тем, который находится непосредственно перед ним.Например: remove_if вызывается для вектора, чтобы удалить все 0 элементов:
0 1 1 0 1 0
приводит к:
1 1 1 0 1 0
Обратите внимание, что вектор еще не является правильным.Это потому, что remove_if
возвращает итератор к последнему действительному элементу ... он не изменяет размер вектора автоматически.Вам все еще нужно вызвать v.erase()
на итераторе, возвращенном из вашего вызова на remove_if
.
Пример ниже
#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)
}