Search code examples
c++c++03erase-remove-idiom

Using negation of UnaryPredicate in erase-remove idiom


Consider the following scenario:

bool is_odd(int i)
{
    return (i % 2) != 0;  
}
int main()
{
    // ignore the method of vector initialization below.
    // assume C++11 is not to be used.
    std::vector<int> v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::vector<int> v2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    
    // removes all odd numbers, OK
    v1.erase( std::remove_if(v1.begin(), v1.end(), is_odd), v1.end() );

    // remove all even numbers
    v2.erase( std::remove_if(v2.begin(), v2.end(), ???), v2.end() );
}

Can I use the same is_odd() UnaryPredicate to remove even numbers as expected in the last line of main(). Or will I have to necessarily write a is_even() even though it will be nothing but:

bool is_even(int i)
{
    return !is_odd(i);  
}

Solution

  • check the std::not1 function. it does what you want.

    v2.erase( std::remove_if(v2.begin(), v2.end(), std::not1(std::ptr_fun(is_odd))), v2.end() );
    

    Live example

    Anyway, if it is up to me plus C++11 is available I would prefere:

     v2.erase( std::remove_if(v2.begin(), v2.end(), [&](auto/* or the type */ const& item){return !is_odd(item);}), v2.end() );
    

    because as far as I remember std::not1 was helpful before lambda was available.