Come usare std :: find / std :: find_if con un vettore di oggetti di class personalizzati?

Ho una class che rappresenta un utente chiamato Nick e voglio usare std::find_if su di esso, dove voglio trovare se il vettore della userlist ha un object incluso con lo stesso nome utente che ho inserito. Ho fatto alcuni tentativi cercando di creare un nuovo object Nick per il nome utente che voglio testare e sovraccaricare l’ == operator e poi provare a usare find/find_if sull’object:

  std::vector userlist; std::string username = "Nicholas"; if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) { std::cout << "found"; } 

Ho sovraccaricato l’ == operator per confrontare Nick == Nick2 dovrebbe funzionare, ma la funzione restituisce l’ error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion) .

Ecco la mia class Nick per riferimento:

 class Nick { private: Nick() { username = interest = email = ""; is_op = false; }; public: std::string username; std::string interest; std::string email; bool is_op; Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) { Nick(); username = d_username; interest = d_interest; email = d_email; is_op = d_is_op; }; Nick(std::string d_username, bool d_is_op) { Nick(); username = d_username; is_op = d_is_op; }; friend bool operator== (Nick &n1, Nick &n2) { return (n1.username == n2.username); }; friend bool operator!= (Nick &n1, Nick &n2) { return !(n1 == n2); }; }; 

    Devi definire l’operatore == con due oggetti al di fuori della tua class, come funzione dello strumento, non come membro.

    Quindi per renderlo amico basta mettere la dichiarazione della funzione all’interno della class.

    prova qualcosa come questo:

     class Nick { public: friend bool operator== ( const Nick &n1, const Nick &n2); }; bool operator== ( const Nick &n1, const Nick &n2) { return n1.username == n2.username; } 

    Anche la tua ricerca dovrebbe assomigliare a questa:

     std::find(userlist.begin(), userlist.end(), Nick(username, false) ); 

    Non c’è bisogno di “nuovo”.

    Se stai usando C ++ 0X puoi usare una semplice espressione lambda

     std::string username = "Nicholas"; std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){ return n.username == username; }) 

    So che volevi sovraccaricare l’operatore == , ma la stessa cosa può essere facilmente eseguita con un predicato:

     struct UsernameIs { UsernameIs( string s ) : toFind(s) { } bool operator() (const Nick &n) { return n.username == toFind; } string toFind; }; int main() { vector vn(10); string nameToFind = "something"; find_if(vn.begin(), vn.end(), UsernameIs(nameToFind)); } 

    Nota che in C ++ 0x, puoi fare la stessa cosa con un’espressione lambda in modo molto più conciso.

    Stai passando un puntatore alla funzione di ricerca. Rilascia il nuovo:

     std::find(userlist.begin(), userlist.end(), Nick(username, false)) 

    Inoltre, i tuoi operatori dovrebbero accettare i loro argomenti con riferimento const, non li modificano.

     bool operator== (const Nick &n1, const Nick &n2) 

    Sto notando che stai cercando di chiamare un costruttore da un altro in questo modo:

     Nick(std::string d_username, bool d_is_op) { Nick(); ... 

    Beh, mi dispiace, ma questo non funziona. La linea Nick() crea solo un temporaneo e non influisce su this . L’inoltro del costruttore è ansible solo in C ++ 0x (il prossimo standard)

    Per quanto riguarda il tuo problema, questa domanda posta un paio di giorni fa su binary_search copre gli stessi motivi. La risposta migliore è semplicemente fantastica.

    Restrizione mistica su std :: binary_search

    HTH.

    PS Idealmente questo dovrebbe essere stato un commento, ma è semplicemente troppo prolisso

    Puoi usare boost :: bind

     std::find_if( userlist.begin(), userlist.end(), boost::bind( & Nick::isFound, _1 ) ); 

    basta implementare bool Nick :: isFound ()

    Puoi anche passare i criteri

     std::find_if( userlist.begin(), userlist.end(), boost::bind( & Nick::compare, _1, nick ) ); 

    strumento

     bool Nick::compare( const Nick & nick ) { return this->username == nick.username; }