Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using std::ptr_fun for a member function

Tags:

c++

c++03

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 fails to negate the effect of is_odd() because it is a member function. The call to std::ptr_fun() fails.

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

like image 409
CinCout Avatar asked Dec 17 '15 10:12

CinCout


2 Answers

There are multiple issues with using A::is_odd(int) as a unary predicate, especially when it needs to be used with std::not1():

  1. A call to A::is_odd(int) takes two arguments: the implicit object ("this") and the visible int argument.
  2. It isn't a function object defining argument_type and result_type.

Properly using this member function as a unary predicate requires two steps:

  1. Adapting the member function pointer to be a suitable function object, e.g., using one of the std::mem_*fun functions.
  2. Binding the first argument to a suitable object, with a non-C++11 compiler probably using std::bind1st().

With a C++11 compiler things are a lot easier because std::bind() take care of both of these. Assuming it is used from a member of A:

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

The same with a pre-C++11 compiler is somewhat harder. The use in std::remove_if() would 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());
like image 179
Dietmar Kühl Avatar answered Oct 16 '22 20:10

Dietmar Kühl


Just make is_odd static, so it won't require an implicit this parameter:

static bool is_odd(int i)

It doesn't use any member variables or other member functions anyway.

like image 34
John Zwinck Avatar answered Oct 16 '22 21:10

John Zwinck