2016-03-23 10 views
7

Das folgende Programm kompiliert nicht. Aber wenn ich operator== nicht auskommentiere, kompiliert es. Warum ist operator== noch benötigt, wenn ich bereits FooEqualKann nicht vergleichen std :: unorded_set mit benutzerdefinierten KeyEqual

#include <cstddef> 
#include <unordered_set> 

struct Foo { 
}; 

struct FooHasher { 
    size_t operator()(const Foo&) const { 
    return 1; 
    } 
}; 

struct FooEqual { 
    bool operator()(const Foo& lhs, const Foo& rhs) const { 
    return true; 
    } 
}; 

// bool operator==(const Foo& lhs, const Foo& rhs) { 
// return true; 
// } 

int main() { 
    std::unordered_set<Foo, FooHasher, FooEqual> s1; 
    std::unordered_set<Foo, FooHasher, FooEqual> s2; 
    (void)(s1 == s2); 
    return 0; 
} 
+0

Muss ein Fehler in der Implementierung sein ... es sei denn, die Spezifikation besagt, dass 'KeqEqual' nur zum Einfügen/Suchen verwendet wird und dass' std :: unordered_set :: operator == 'prüft, ob zwei Sätze gleich sind, abhängig davon, ob die einzelnen Elemente vergleichen gleich? Braucht hier vielleicht einen C++ - Anwalt. – dreamlax

Antwort

2

„23.2.5 ungeordnete assoziative Container“ stellt fest:

zwei ungeordneten Behältern a und B Vergleichen Sie gleich falls a.size() == b.size() und für jedes Äquivalent = Schlüsselgruppe [Ea1, Ea2) erhalten von a.equal_range (Ea1) existiert eine äquivalente Schlüsselgruppe [Eb1, Eb2) erhalten aus b.equal_range (Ea1), so dass Abstand (Ea1, Ea2) == Abstand (Eb1, Eb2) und is_permutation (Ea1, Ea2, Eb1) wahr zurückgibt.

Dies ist alles, was auf die Gleichheit der ungeordneten Container in Bezug auf std::is_permutation() definiert ist.

Der wichtige Teil ist, dass dies die drei Argumentform von std::is_permutation() verweist, und nicht die vier Argumentform!

Mit anderen Worten, das ganze Kartenhaus wird auf den Standard operator== für den Inhalt des ungeordneten Containers statt der offiziellen Vergleichsfunktion des Containers reduziert.

Das ist mein gelesen zu diesem Thema.

3

zu http://en.cppreference.com/w/cpp/container/unordered_set/operator_cmp Nach Sie in der Tat brauchen die operator== zum Vergleich (Ich habe keinen Zugriff auf die Standard-jetzt - ich werde versuchen, mit der aktualisieren spezifisches Angebot irgendwann morgen):

Das Verhalten ist undefiniert, wenn Key nicht EqualityComparable ist.

Das Verhalten ist auch nicht definiert, wenn Hash und KeyEqual nicht über das gleiche Verhalten auf lhs und rhs oder wenn der Gleichheit Vergleichsoperator für Key ist nicht eine Verfeinerung der Trennwand in äquivalenten Schlüsseln Gruppen von KeyEqual eingeführt (das heißt, wenn zwei Tasten, die gleich fallen in verschiedene Partitionen zu vergleichen)