Sign in to follow this  

stl::list remove_if

This topic is 3664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I did like to know how should i go about doing if i wish to set the predicate function as a member function of a class? e.g:
class CTest
{
private:
   std::list<int> IntList;

   bool IsPositive(int a)
   {
       return (a > 0) ? true : false;
   };

public:
   void RemovePositiveNumber()
   {
      IntList.remove_if(IsPositive);
   };
}

CTest MyTest;
MyTest.RemovePositiveNumber();
It seems that remove_if does not accept IsPositive as a predicate. Is it syntatically wrong to put IsPositive as the predicate?

Share this post


Link to post
Share on other sites
The predicate should be callable on it's own, but a member function needs an instance to be called. Making IsPositive a static member function, or free standing which I would prefer in this case, should be enough.

Share this post


Link to post
Share on other sites
I don't really understand the method:

IntList.remove_if(std::bind1st(std::mem_fun(&CTest::IsPositive),this));




I understand what bind1st is use for. However why is it that I need to bind the (this) pointer to the 1st argument of the mem_fun returned value, which is mem_fun_t?


Edit: If the predicates require 2 arguments like sort? Will mem_fun still work?

[Edited by - littlekid on December 3, 2007 12:23:53 PM]

Share this post


Link to post
Share on other sites
A class could also be used.

struct IsPositive
{
bool operator()(int a)
{
return a > 0;
};
};


...

void RemovePositiveNumber()
{
IntList.remove_if(IsPositive());
};

Share this post


Link to post
Share on other sites
Quote:
Original post by littlekid
I don't really understand the method:
*** Source Snippet Removed ***

I understand what bind1st is use for. However why is it that I need to bind the (this) pointer to the 1st argument of the mem_fun returned value, which is mem_fun_t?


Edit: If the predicates require 2 arguments like sort? Will mem_fun still work?


For some information about the funky pointer to member function syntax, see here. If you're not a fan of obscure C++ syntax, look away now [smile]. (I think this post is a little beyond 'For Beginners' anyway)

With the class in question, std::mem_fun returns a functor that looks something like this (this is simplified though, templates removed etc):

struct Functor
{
bool (CTest::*function)( int );

bool operator()( CTest *instance, int argument )
{
return (instance->*function)(argument);
}
};



This functor requires two arguments.

std::remove_if takes a functor that takes a single argument. Using std::bind1st, we 'bind' the first parameter, in this case the CTest pointer, to 'this'. The resulting functor looks something like this:

struct Functor
{
bool (CTest::*function)( int );
CTest *instance;

bool operator()( int argument )
{
return (instance->*function)(argument);
}
};



As for functors making use of member functions taking two (or more) arguments, boost::bind may be able to handle it (I've never had reason to use it).

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
As for functors making use of member functions taking two (or more) arguments, boost::bind may be able to handle it (I've never had reason to use it).

Yes, boost::bind does this very nicely, something like this:
boost::bind(&Class::memberFunction, this, _1, _2);

adding additional _N as needed. You can also swizzle arguments by changine the order of _Ns, or by omitting or duplicating them.

Share this post


Link to post
Share on other sites
Ok thanks alot, I now understand the how to use bind1st and mem_fun. Maybe if i need to use a predicate that needs 2 argument, i might make it static, and use bind1st /bind2nd when needed.

Or could I write my own template that is similar to mem_fun1_t? but in this case accepting 2 arg? e.g a self created mem_fun2_t

Share this post


Link to post
Share on other sites
Quote:
Original post by littlekid
Or could I write my own template that is similar to mem_fun1_t? but in this case accepting 2 arg? e.g a self created mem_fun2_t


These can be tricky beasties to get right, so i would suggest using boost::bind instead, or just sticking to static/free functions. As far as I recall, boost::bind is a header library, meaning that you only need the headers to use it, rather than having to use a lib or dll, making it much simpler to distribute.

Share this post


Link to post
Share on other sites

This topic is 3664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this