2009-05-25 24 views
23

Sto tentando di assegnare un tipo personalizzato come chiave per std :: map. Ecco il tipo che sto usando come chiave.Tipi personalizzati come chiave per una mappa - C++

struct Foo 
{ 
    Foo(std::string s) : foo_value(s){} 

    bool operator<(const Foo& foo1) { return foo_value < foo1.foo_value; } 

    bool operator>(const Foo& foo1) { return foo_value > foo1.foo_value; } 

    std::string foo_value; 
}; 

Quando utilizzato con std :: map, sto ottenendo il seguente errore.

error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const Foo' (or there is no acceptable conversion) c:\program files\microsoft visual studio 8\vc\include\functional 143 

Se cambio la struct come il sotto, tutto ha funzionato.

struct Foo 
{ 
    Foo(std::string s) : foo_value(s) {} 

    friend bool operator<(const Foo& foo,const Foo& foo1) { return foo.foo_value < foo1.foo_value; } 

    friend bool operator>(const Foo& foo,const Foo& foo1) { return foo.foo_value > foo1.foo_value; } 

    std::string foo_value; 
}; 

Nulla è cambiato tranne rendendo gli overload dell'operatore come amico. Mi chiedo perché il mio primo codice non funziona?

Qualche idea?

risposta

32

ho il sospetto è necessario

bool operator<(const Foo& foo1) const; 

Annotare il const dopo gli argomenti, questo è quello di rendere la "vostra" (il lato sinistro nel confronto) oggetto costante.

Il motivo per cui è necessario un solo operatore è che è sufficiente implementare l'ordine richiesto. Per rispondere alla domanda astratta "deve venire prima b?" è sufficiente sapere se a è inferiore a b.

+0

Grazie. Questo ha fatto il trucco. –

+0

Puoi entrare in maggiori dettagli? Perché hai solo bisogno dell'operatore ? – bobobobo

+14

perché è possibile derivare operatore> e operatore == dall'operatore <. '(b b)', quindi c'è l'operatore>. e, '(! (A skrebbel

3

Probabilmente sta cercando operatori membri const (qualunque sia il nome corretto). questo funziona (nota const):

bool operator<(const Foo& foo1) const { return foo_value < foo1.foo_value;} 

EDIT: soppresso operator> dalla mia risposta in quanto non era necessario (copia/incolla da domanda) ma era attirando commenti :)

Nota: Sono 100% sicuro di aver bisogno di quello const perché ho compilato l'esempio.

+2

Non è necessario> –

+0

Stackoverflow divertente mostra la risposta precedente 10 minuti fa ma quando invio la mia risposta non ce n'era ancora ... quindi la stessa risposta – stefanB

+0

Poiché l'oggetto è costante, la funzione const sarebbe necessaria. – siddhusingh

0

Nota il const dopo gli argomenti, questo è per rendere costante la "tua" (la parte sinistra nel confronto).

Potresti per favore approfondire questo? Perché se fai il membro const (che per quanto ne so significa che non può cambiare lo stato dell'oggetto - ad esempio modificare le variabili private) garantisce che "tuo" sarà il lato sinistro?

0

Potrebbe per favore approfondire su questo? Perché se fai il membro const (che per quanto ne so significa che non può cambiare lo stato dell'oggetto - ad esempio modificare le variabili private) garantisce che "tuo" sarà il lato sinistro?

Non ho ancora il rappresentante per commentare questo.

const non magicamente garantisce che "tuo" sarà il lato sinistro. Il poster stava dicendo che il lato sinistro (cioè x in x < y) è l'oggetto su cui viene chiamato il confronto. Proprio come proteggi i membri di y da change con const sull'argomento all'operatore <, vuoi anche proteggere i membri di x da change con const alla fine della firma del metodo.

Problemi correlati