2009-05-25 22 views
23

Próbuję przypisać niestandardowy typ jako klucz dla std :: map. Oto typ, którego używam jako klucza.Typy niestandardowe jako kluczowe dla mapy - 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; 
}; 

Kiedy stosować std :: map, otrzymuję następujący błąd.

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 

Jeśli zmienię strukturę jak poniżej, wszystko zadziałało.

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; 
}; 

Nic się nie zmieniło z wyjątkiem dokonywania przeciążenia operatora jako znajomego. Zastanawiam się, dlaczego mój pierwszy kod nie działa?

Jakieś myśli?

Odpowiedz

32

Podejrzewam trzeba

bool operator<(const Foo& foo1) const; 

Zanotować const po argumentów jest to, aby „twój” (strona lewa w porównaniu) obiekt stały.

Powód, dla którego potrzebny jest tylko jeden operator, oznacza, że ​​wystarczy wprowadzić wymagane zamówienie. Aby odpowiedzieć na abstrakcyjne pytanie "czy trzeba przyjść przed b?" wystarczy wiedzieć, czy a jest mniejsze niż b.

+0

Dzięki. To wystarczyło. –

+0

Czy możesz wejść w szczegóły? Dlaczego potrzebujesz tylko operatora <, a nie operatora == lub operatora>? – bobobobo

+14

, ponieważ możesz wyprowadzić operator> i operator == z operatora <. '(b b)', więc jest operator>. i '(! (A skrebbel

3

Prawdopodobnie szuka operatorów członów składowych (bez względu na poprawną nazwę). Działa to (uwaga const):

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

EDIT: skreślony operator> z moją odpowiedź, ponieważ nie był potrzebny (kopiuj/wklej z pytaniem), ale to było przyciągnięcie uwagi :)

Uwaga: Jestem 100% pewności, że potrzebujesz const, ponieważ skompilowałem przykład.

+2

Nie potrzebujesz> –

+0

Funny stackoverflow pokazuje poprzednią odpowiedź 10 minut temu, ale kiedy przesyłam swoją odpowiedź, nie było jeszcze żadnej ... stąd ta sama odpowiedź – stefanB

+0

Ponieważ obiekt jest stałą funkcją const byłaby wymagana. – siddhusingh

0

Zwróć uwagę na const po argumentach, aby stała stała "twoja" (lewa strona w porównaniu).

Czy mógłbyś to wyjaśnić? Dlaczego, jeśli uczynisz element const (który, o ile wiem, że nie może zmienić stanu obiektu - np. Modyfikuje prywatnych zmiennych), gwarantuje, że "twój" będzie po lewej stronie?

0

Czy mógłbyś to wyjaśnić? Dlaczego, jeśli uczynisz element const (który, o ile wiem, że nie może zmienić stanu obiektu - np. Modyfikuje prywatnych zmiennych), gwarantuje, że "twój" będzie po lewej stronie?

Nie mam jeszcze przedstawiciela do komentowania tego.

const nie zapewnia magicznie, że "twoje" będzie po lewej stronie. Plakat mówi, że strona lewa (tj. X w x < y) jest obiektem, na który wywoływane jest porównanie. Podobnie jak chronisz członków y przed zmianą za pomocą const argumentu operatora <, chcesz również chronić członków x przed zmianą za pomocą const na końcu podpisu metody.

Powiązane problemy