[lambda]Predicate construction
I tried to create a predicate based on lambda expressions.
The attempt failed with compiler errors so finally I created
a struct to do the job.
The problem is:
I have a vector with pointers of objects of class Event.
vector
Anakreon wrote:
struct event_locator: public unary_function
{ int tId; event_locator(const int tid) : tId(tid) {} const bool operator() (Event* e) { return e->hasTransaction() && e->getTransaction().getId() == tId; } };
The best (IMO) approach would be to define bool has_transaction_with_id( Event /*const?*/ * e, int id ) { return e->hasTransaction() && e->getTransaction().getId() == id; } and then use bind( has_transaction_with_id, _1, tid ) as the predicate. You can also define hasTransactionWithId as a member of Event and then use bind( &Event::hasTransactionWithId, _1, tid ). You can use bind( &Event::hasTransaction, _1 ) && bind( &Transaction::getId, bind( &Event::getTransaction, _1 ) ) == tid but I'm not sure that you'd want to.
Peter Dimov wrote:
Anakreon wrote:
struct event_locator: public unary_function
{ int tId; event_locator(const int tid) : tId(tid) {} const bool operator() (Event* e) { return e->hasTransaction() && e->getTransaction().getId() == tId; } }; The best (IMO) approach would be to define
bool has_transaction_with_id( Event /*const?*/ * e, int id ) { return e->hasTransaction() && e->getTransaction().getId() == id; }
and then use bind( has_transaction_with_id, _1, tid ) as the predicate. You can also define hasTransactionWithId as a member of Event and then use bind( &Event::hasTransactionWithId, _1, tid ).
It may be more useful to generalise this further, depending on how often it's used. (Also, it's considered better taste to not add members that don't need to be members) Optionally: // Would be safer with a overloadable transaction id type bool operator==(Event const& e, int id) { // as above, but e. , not e-> } and then use: find_if(..., *_1 == tId); If that makes any sense for Events, and you are doing it a lot (but if you are, do you really want a lambda function?).
You can use
bind( &Event::hasTransaction, _1 ) && bind( &Transaction::getId, bind( &Event::getTransaction, _1 ) ) == tid
but I'm not sure that you'd want to.
Yes, lambda is rather weak when it comes to members, due to no fault of the designers. Btw, the & op isn't needed anymore, bind takes function references as well.
It may be more useful to generalise this further, depending on how often it's used. (Also, it's considered better taste to not add members that don't need to be members) Optionally:
// Would be safer with a overloadable transaction id type bool operator==(Event const& e, int id) { // as above, but e. , not e-> }
and then use: find_if(..., *_1 == tId);
It doesn't look like good practice to declare the equality operator compare an Event object with an int.
Anakreon wrote:
It may be more useful to generalise this further, depending on how often it's used. (Also, it's considered better taste to not add members that don't need to be members) Optionally:
// Would be safer with a overloadable transaction id type bool operator==(Event const& e, int id) { // as above, but e. , not e-> }
and then use: find_if(..., *_1 == tId);
It doesn't look like good practice to declare the equality operator compare an Event object with an int.
Indeed. Hence the comment about having a specific transaction type. Only do this if it makes logical sense, of course.
Peter Dimov wrote:
Anakreon wrote:
struct event_locator: public unary_function
{ int tId; event_locator(const int tid) : tId(tid) {} const bool operator() (Event* e) { return e->hasTransaction() && e->getTransaction().getId() == tId; } }; The best (IMO) approach would be to define
bool has_transaction_with_id( Event /*const?*/ * e, int id ) { return e->hasTransaction() && e->getTransaction().getId() == id; }
I intended to use lambda in order to avoid declaration of functions or structs for STL algorithms. If I need to declare the function above then I find no reason to use lambda at all.
You can use
bind( &Event::hasTransaction, _1 ) && bind( &Transaction::getId, bind( &Event::getTransaction, _1 ) ) == tid
but I'm not sure that you'd want to. It looks to complex.
Thanks Peter for the response.
participants (3)
-
Anakreon
-
Peter Dimov
-
Simon Buchan