2012-08-23 12 views
8

Sto usando i set. Io uso una struttura personalizzata come chiave. Sto inserendo un valore e sto cercando di trovare il valore inserito. Ma non sembra mai trovare l'elemento.C++ std :: set Trova funzione overloading == operatore

Ho sostituito sia l'operatore == che l'operatore <.

ecco il codice della struttura:

struct distance_t 
{ 
public: 
int id; 
double distance; 

bool operator<(const distance_t& rhs) const 
{ 
    if(distance < rhs.distance) 
     return true; 
    else 
     return false; 
} 

bool operator==(const distance_t& rhs) 
{ 
    if(id == rhs.id) 
     return true; 
    else 
     return false; 
} 
}; 

E questo è il codice della principale

int main() 
{ 
    set<distance_t> currentSet; 

    distance_t insertDistance; 
    insertDistance.id =1; 
    insertDistance.distance = 0.5; 

    currentSet.insert(insertDistance); 

    distance_t findDistance; 
    findDistance.id = 1; 

    assert(currentSet.find(findDistance) != currentSet.end()); 
} 

Fallisce sempre nella dichiarazione assert. Che cosa sto facendo di sbagliato?

Modifica -Ok ora capisco che non utilizza affatto l'operatore ==. Ecco quello che voglio. Ho bisogno che la struttura dei dati sia ordinata per distanza. Ma dovrei riuscire a rimuoverlo usando l'id. Esiste un modo pulito o un datastructure già esistente per farlo?

+2

Un suggerimento di stile: dove si ha 'if (expr) return true; altrimenti restituisci false; 'puoi invece semplicemente restituire expr;' – Blastfurnace

+1

Cosa c'è di sbagliato con solo 'return id

+0

@Blastfurnace Anche le parentesi non sono necessarie. –

risposta

8

fallisce perché il meno-che il confronto utilizza distance_t::distance, che non si sta impostando in findDistance:

distance_t findDistance; 
findDistance.id = 1; 

std::set non usa operator== per qualsiasi cosa. Utilizza solo operator<. Quindi dovresti cambiare la logica per usare distance_t::id.

Se si desidera effettuare la ricerca per id senza cambiare ordinamento del set, è possibile utilizzare std::find:

set<distance_t>::iterator it = std::find(currentSet.begin(), 
             currentSet.end(), 
             findDistance); 

Questo userà il vostro operator==. Tieni presente che questo ha una complessità temporale lineare.

+0

Voglio usare la distanza per ordinare gli elementi ma voglio che l'id trovi l'elemento. È possibile? –

+1

L'ordine di TheFlyingDutchman viene utilizzato per la ricerca (set è un albero binario). Quindi non è possibile avere l'ordinamento e la ricerca disaccoppiati. È possibile incorporare 'id' nella logica dell'ordine, in realtà dipende da cosa si sta cercando di ottenere. – juanchopanza

+1

@TheFlyingDutchman Puoi fare in modo che 'operator <' guardi prima la distanza e, se sono uguali, guarda id. Ciò preserverebbe l'ordine che stai cercando. (E cambia anche 'operator ==' per esaminare entrambi i campi.) Ma ciò significa che non puoi cercare se hai solo l'id. – hvd

4

Perché operator== non viene invocato affatto. Confrontando elementi è simile:

!(a < b) && !(b < a) 

In altre parole, esso utilizza operator<.

1

Poiché non è stato assegnato un valore a findDistance.distance, il risultato del minore è il confronto non definito.

Si noti che le definizioni dell'eguaglianza e meno degli operatori di confronto sono pericolose, perché è facile definire le istanze di distance_t dove il loro risultato è incoerente. Un esempio sono due istanze con la stessa distanza ma diversi ID.