Using std :: ptr_fun for a member function

Consider the following:

class A { public: bool is_odd(int i) { return (i % 2) != 0; } void fun() { std::vector<int> v2; v2.push_back(4); v2.push_back(5); v2.push_back(6); // fails here v2.erase(std::remove_if(v2.begin(), v2.end(), std::not1(std::ptr_fun(is_odd))), v2.end()); } }; 

The above code cannot negate the effect of is_odd() , since it is a member function. The call to std::ptr_fun() not performed.

How to make it work? Note that I want is_odd() be a non-static member function.

+8
c ++ c ++ 03
source share
2 answers

There are several problems with using A::is_odd(int) as a unary predicate, especially when you need to use it with std::not1() :

  • A::is_odd(int) call to A::is_odd(int) takes two arguments: an implicit object (" this ") and a visible int argument.
  • It is not a function object that defines argument_type and result_type .

Proper use of this member function as a unary predicate requires two steps:

  • Adaptation of a member function pointer is a suitable function object, for example, using one of the functions std::mem_*fun .
  • Binding the first argument to a suitable object with a compiler other than C ++ 11, possibly using std::bind1st() .

Using the C ++ 11 compiler is much simpler because std::bind() will take care of all of these. Assuming it is used from member A :

 ... std::not1(std::bind(&A::is_odd, this, std::placeholders::_1)) ... 

The same thing with the pre-C ++ 11 compiler is somewhat more complicated. Usage in std::remove_if() will look something like this:

 v2.erase( std::remove_if(v2.begin(), v2.end(), std::not1(std::bind1st(std::mem_fun(&A::is_odd), this))), v2.end()); 
+8
source share

Just make is_odd static, so it will not require an implicit this parameter:

 static bool is_odd(int i) 

In any case, it does not use any member variables or other member functions.

0
source share

All Articles