2013-04-07 9 views
14

Ho il seguente codice per creare un unordered_set<Interval>. Questo compila bene.Inserimento in unordered_set con funzione hash personalizzata

struct Interval { 
    unsigned int begin; 
    unsigned int end; 
    bool updated; //true if concat. initially false 
    int patternIndex; //pattern index. valid for single pattern 
    int proteinIndex; //protein index. for retrieving the pattern 
}; 

struct Hash { 
    size_t operator()(const Interval &interval); 
}; 


size_t Hash::operator()(const Interval &interval){ 
    string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex); 
    return hash<string>()(temp); 
} 

unordered_set<Interval, string, Hash> test; 

Tuttavia, non posso compilare quando provo ad inserire utilizzando questo codice:

for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){ 
    test.insert((*i)); 
    } 

Inoltre, non posso determinare quale sia il problema dei messaggi di errore.

Ecco un esempio:

note: candidate is: 
note: size_t Hash::operator()(const Interval&) 
note: candidate expects 1 argument, 2 provided 

ho pensato che ho fornito solo 1 argomento ...

Chiunque vede un problema con il mio codice di inserimento? Per favore aiutatemi, se potete, sto cercando una soluzione da un po 'ora.

EDIT:

Ecco il nuovo codice di istanza: unordered_set<Interval, Hash> test; Tuttavia, sono ancora ricevendo un gran numero di messaggi di errore. Es:

note: candidate is: 
note: size_t Hash::operator()(const Interval&) <near match> 
note: no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’ 
+0

Ho aggiornato la mia risposta, che dovrebbe risolvere il problema che stai descrivendo nella tua modifica –

+0

http://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as- the-key –

risposta

25

Primo problema:

Si passa string come secondo argomento modello per l'esemplificazione del modello unordered_set<> di classe. The second argument should be the type of your hasher functor e std::string non è un oggetto richiamabile.

Forse voleva dire scrivere:

unordered_set<Interval, /* string */ Hash> test; 
//      ^^^^^^^^^^^^ 
//      Why this? 

Inoltre, vi suggerirei di usare nomi diversi begin e end per le variabili (membro), dal momento che questi sono i nomi di algoritmi della libreria standard C++.

Secondo problema:

Si dovrebbe tenere a mente, that the hasher function should be qualified as const, in modo che il funtore dovrebbe essere:

struct Hash { 
    size_t operator() (const Interval &interval) const { 
    //           ^^^^^ 
    //           Don't forget this! 
    string temp = to_string(interval.b) + 
        to_string(interval.e) + 
        to_string(interval.proteinIndex); 
    return (temp.length()); 
    } 
}; 

Terzo problema:

Infine, se si desidera std::unordered_set a essere in grado di lavorare con oggetti di tipo Interval, è necessario definire un operatore di uguaglianza coerente con il proprio hash funzione. Per impostazione predefinita, se non si specifica alcun argomento di tipo come terzo parametro del modello di classe std::unordered_set, verrà utilizzato operator ==.

Attualmente non si dispone di alcun sovraccarico di operator == per la classe Interval, quindi è necessario fornire uno.Per esempio:

inline bool operator == (Interval const& lhs, Interval const& rhs) 
{ 
    return (lhs.b == rhs.b) && 
      (lhs.e == rhs.e) && 
      (lhs.proteinIndex == rhs.proteinIndex); 
} 

Conclusione:

Dopo tutte le modifiche di cui sopra, è possibile visualizzare il codice di compilazione in questo live example.

+0

Capisco. Grazie per l'aiuto! – user2052561

+0

@ user2052561: Ho aggiornato la risposta per includere più correzioni –

+0

Wow! Molte grazie. Questa è stata la mia prima volta che ho usato 'unordered_set's ... – user2052561

Problemi correlati