2010-10-22 2 views
1

Comment utiliser find_if avec une liste std :: si la liste contient des structures? Ma première à cette tentative de pseudo-code ressemble à ceci:find int dans struct avec find_if pour std :: list avec structs

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

Le problème ici est que le prédicat ne soit pas directement visible dans la liste mais à l'intérieur event.object.return_number(). Comment suis-je supposé faire référence à un int qui est imbriqué dans la structure et qui nécessite l'accès à une méthode get.

Répondre

2

vous pouvez utiliser une classe foncteur (qui ressemble à une fonction, mais vous permet d'avoir l'état, telles que la 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)); 
+0

Merci, c'est très probablement ce que je vais faire. Bien que je pensais juste à surcharger l'opérateur == dans ma structure d'événement, quelle est votre opinion là-dessus? Puis-je utiliser un événement en tant que prédicat? – foo

+0

@foo: Probablement une mauvaise idée! Il n'est pas évident de voir ce que fait 'e == 3'. La surcharge de l'opérateur doit être réservée aux situations où la signification est sans ambiguïté. –

+0

Peu importe, j'ai utilisé le foncteur et cela a parfaitement fonctionné. Merci encore. – foo

2

En C++ 0x, que votre compilateur probablement déjà partie des outils, vous pouvez effectuer les opérations suivantes:

find_if(cal.begin(), cal.last(), [&](const Event& e) 
     { 
      return e.object.return_number() == value_to_find; 
     }); 
+0

Merci, je pense que dans ce cas, je dois rester loin de C++ 0x pour des raisons de compability. Je garderai cela à l'esprit cependant. – foo

0

La façon la plus simple (en (simple, non, mais) l'absence de 11 C++) est un comparateur personnalisé:

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)); 
+1

Malheureusement, la fonction de prédicat pour 'std :: find_if' est unaire ... –

+0

@Oli: Merci; corrigée. –

+0

Merci pour l'aide. – foo

1

Vous définissez votre chose prédicat comme ceci:

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)); 
+0

Merci, j'ai fini par utiliser le foncteur qui a fait ce que je voulais ici. – foo