Wenn ich std :: map verwende, sollte ich den Operator == für den Schlüsseltyp überladen?

7

Die std :: map sollte keine duplizierten Schlüssel haben. Wie weiß ich also, dass ich einen duplizierten Schlüssel habe, wenn ich einen benutzerdefinierten Typ habe? Muss ich den Overload-Operator overload ==? Oder es wird implizit erstellt?

Laut Dokumentation brauche ich nur den Operator & lt; aber das ist nicht genug, um die Uneinheitlichkeit der Schlüssel zu erhalten.

Betrachten Sie dieses Beispiel:

%Vor%     
Hugo Sadok 23.11.2013, 21:34
quelle

4 Antworten

16

std::map interessiert sich nicht für die literale Unicity der Schlüssel. Es kümmert sich um Schlüssel Äquivalenz . Die Schlüssel a und b sind per Definition äquivalent, wenn weder a < b noch b < a wahr sind.

Beachten Sie auch, dass std::map nicht direkt operator < verwendet. std::map weiß nichts über operator < . Stattdessen verwendet std::map das Vergleichsprädikat, dessen Typ als dritter Parameter von std::map template angegeben ist. Der Standardwert dieses Parameters ist std::less . Die Implementierung von std::less delegiert den Vergleich an operator < (sofern nicht anders spezialisiert). So kommt operator < ins Spiel. Sie können aber immer ein eigenes Prädikat angeben, das nicht notwendigerweise operator < verwendet.

Aber in jedem Fall ist der Schlüsselmoment hier, dass std::map einen "weniger" Vergleich und nur einen "weniger" Vergleich verwendet. Es braucht keine "Gleichheitsvergleiche" und kümmert sich nicht darum.

In der Zwischenzeit wäre std::unordered_map eine andere Geschichte. Es beruht auf einem nicht-ordnenden Gleichheitsvergleich, der durch ein Prädikat angegeben wird. Standardmäßig ist es std::equal_to . Die Implementierung von std::equal_to delegiert den Aufruf an operator == (sofern nicht anders spezialisiert).

    
AnT 23.11.2013, 21:41
quelle
3

operator & lt; ist genug. Die Gleichheit kann durch Testen eines & lt; b und b & lt; beide kehren falsch zurück.

    
Jasper 23.11.2013 21:37
quelle
2

Sie sollten operator< überladen.

Das std::map vergleicht die Schlüssel mit !(a < b) && !(b < a) als Test für die Eindeutigkeit.

    
NicholasM 23.11.2013 21:38
quelle
2

Die assoziativen Container der Reihenfolge verwenden nur eine strikte schwache Reihenfolge, um sie zu identifizieren. Sie werden operator==() nicht verwenden. Der einzige Vergleich zum Suchen von Objekten ist das dritte Template-Argument für std::map<K, V, Compare, Allocator> .

Der Vergleich wird verwendet, um Schlüssel in Äquivalenzmengen zu gruppieren. Die zwei Schlüssel k1 und k2 werden als gleichwertig betrachtet, wenn weder k1 kleiner als k2 noch k2 kleiner als k1 :

ist %Vor%

Natürlich werden die assoziativen Container tatsächlich etwas mehr wie

verwenden %Vor%     
Dietmar Kühl 23.11.2013 21:40
quelle

Tags und Links