8

It might be a stupid question but just wonder if there is any workaround. :)

Is there any way to have "Not" in Predicate?

Example:

std::remove_if(s.begin(), s.end(), !IsCorrect); 
//                                 ^

Or, Do I have to create IsNotCorrect function anyways?

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
Michael Sync
  • 4,834
  • 10
  • 40
  • 58
  • possible duplicate of [How can I negate a functor in C++ (STL)?](http://stackoverflow.com/questions/265228/how-can-i-negate-a-functor-in-c-stl) – kennytm Oct 30 '10 at 19:53

2 Answers2

18

You can do it using std::not1, which negates a unary predicate:

#include <functional>

std::remove_if(s.begin(), s.end(), std::not1(std::ptr_fun(IsCorrect)));

If IsCorrect is an Adaptable Function then you don't need ptr_fun, but if it's just a plain function then you do.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • Do note that `std::ptr_fun` is deprecated. I think `std::ref` would work as a replacement here. – ECrownofFire Dec 18 '13 at 23:18
  • @ECrownofFire: Right, `ptr_fun` is made obsolete in C++11. I suppose in principle there's a project for someone, to go through all C++ questions on SO asked prior to 2011 and update their answers with C++11 (and/or C++14) equivalents where a better solution is available ;-) – Steve Jessop Dec 18 '13 at 23:24
1

Also you can try brutforce like this to any predicate in C++11

template<class Predicate>
class not {
    //Has it's inverse predicate
    Predicate _Pred;
public:

    //Construct with arguments
    //required to construct _Pred
    template<class... Args>
    not(Args&&... args);

    //bool operator() with
    //_Pred arguments
    template<class... Args>
    bool operator()(Args&&... args) const;
};

template<class Predicate>
template<class... Args>
not<Predicate>::not(Args&&... args): _Pred(args...) {}

template<class Predicate>
template<class... Args>
bool not<Predicate>::operator()
    (
    Args&&... args
    ) const { return !_Pred(args...); }
  • 1
    Best to forward the arguments both in the constructor and the function call operator: "std::forward< Args >( args ) ...". Nice answer nonetheless. – Ash Aug 02 '14 at 04:36
  • @Ash I answered it at the time when I started to learn variadic templates stuff. Of course, there should be forwarding used) –  Aug 04 '14 at 01:11