tags:

views:

60

answers:

4

Hi,

How can I use find_if with a std::list if the list contains structs? My first pseudo code attempt at this looks like this:

typename std::list<Event>::iterator found = 
    find_if(cal.begin(), cal.last(), predicate); 

The problem here is that the predicate is not directly visible in the list but inside event.object.return_number(). How am I suppose to refer to an int that is nested inside the struct and needs a get method to be accessed.

+1  A: 

In C++0x, which your compiler probably already partially implements, you can do the following:

find_if(cal.begin(), cal.last(), [&](const Event& e) 
        { 
            return e.object.return_number() == value_to_find;
        });
Grozz
Thanks, I think in this case I need to stay away from C++0x for compability reasons. I'll keep this in mind though.
foo
A: 

The (not so simple, but) simplest way (in the absence of C++11) is a custom comparator:

struct CompareMyStruct {
    int n_;
    CompareMyStruct(int n) : n_(n) { }
    bool operator()(const Event& a) const {
        return a.object.return_number() == n_;
    }
};

typename std::list<Event>::iterator found =
    find_if(cal.begin(), cal.last(), CompareMyStruct(123));
Marcelo Cantos
Unfortunately, the predicate function for `std::find_if` is unary...
Oli Charlesworth
@Oli: Thanks; corrected.
Marcelo Cantos
Thanks for the help.
foo
+2  A: 

You can use a functor class (which is like a function, but allows you to have state, such as configuration):

class Predicate
{
public:
    Predicate(int x) : x(x) {}
    bool operator() (const Cal &cal) const { return cal.getter() == x; }
private:
    const int x;
};

std::find_if(cal.begin(), cal.end(), Predicate(x));
Oli Charlesworth
Thanks, this is most likely what I will go for. Although I just thought of overloading operator== inside my Event struct, what is your opinion on that? Could I then use an Event as a predicate?
foo
@foo: Probably a bad idea! It's not clear just from looking at it what `e == 3` is doing. Operator overloading should be reserved for situations where the meaning is unambiguous.
Oli Charlesworth
Never mind, I used the functor and it worked out perfectly. Thanks again.
foo
+1  A: 

You set up your predicate something like this:

struct IsEventObjectReturnNumber
{
   int num;
   explicit IsEventObjectReturnNumber( int n ) : num( n ) {}

   bool operator()(const Event & event ) const
   {
      return event.object.return_number() == num;
   }
};

std::list<Event>::iterator = std::find_if(cal.begin(), cal.end(), IsEventObjectReturnNumber(x));
CashCow
Thank you, I ended up using the functor which did what I wanted here.
foo