2015-07-13 9 views
9

Ich verwende externe Netzwerkbibliothek, die einige magische Strukturen zurückgibt, die geöffnete Sockets darstellen, und die Dokumente sagen, dass sie beim Einfügen in STL-Container mit std::owner_less verglichen werden sollten.C++ 11 unordered_set mit std :: owner_less-like hashing

std::map<MagicStructure, std::shared_ptr<Client>, std::owner_less<MagicStructure>> sockets; 

Allerdings würde ich stattdessen unordered_map verwenden. Wie kann ich es tun? std::owner_less ist ein Komparator und es ist nutzlos für eine Hash-Karte. Beim Eingeben des Quellcodes scheint MagicStructure ein typedef für std::shared_ptr zu sein.

+0

Dies kann eine echte Unterlassung aus dem Standard sein. Wir brauchen etwas wie "owner_equal" und "owner_hash"; Letzteres könnte der Hash der Adresse des Steuerblocks sein. –

+0

Sie könnten den Quellcode anschauen und sehen, ob sie einen Deleter setzen, und wenn ja, welchen Typ. Dann versuche 'get_deleter'. Möglicherweise kann der 'Deleter' als Proxy für den" Eigentümer "verwendet werden. – Yakk

Antwort

2

Leider scheint es, dass Sie ein map verwenden müssen, und nicht unordered_map für ein solches Szenario verwenden können: http://wg21.cmeerw.net/lwg/issue1406

Hash-Unterstützung für die Besitz basierte ¨Aquivalenzrelation nicht durch einen vom Benutzer zur Verfügung gestellt werden kann, definierte Art und Weise, weil Informationen über Besitzfreigabe für Benutzer überhaupt nicht verfügbar ist. Daher bietet die einzige Möglichkeit, die Besitz-basierte Hash-Unterstützung zu bieten, sie intrusiv von der Standardbibliothek anzubieten.

In den anderen Worten, es gespeichert wird (wieder durch get()) und im Besitz Zeiger (die gelöscht wird, wenn Referenzzähler 0 erreicht) in einem shared_ptr: http://www.cplusplus.com/reference/memory/shared_ptr/get/. Um den eigenen Zeiger in einer unordered_map zu verwenden, benötigen Sie die Zeiger hash() und equals() des Besitzers. Aber sie sind nicht in STL zur Verfügung gestellt. Und Sie können sie nicht selbst implementieren (ohne shared_ptr neu zu implementieren und die Definition von MagicStructure zu ändern), da der eigene Zeiger nicht von shared_ptr verfügbar gemacht wird.

+1

http://en.cppreference.com/w/cpp/memory/shared_ptr/owner_before ist relevant, da es deutlicher macht, wie 'a.get() Yakk

0

Die Bestellung von std::owner_less kann leicht in einen Gleichheitsvergleich angepasst werden (a und b sind gleich, wenn keiner dem anderen vorausgeht).

Die Standard-Hashing-Implementierung für std::shared_ptr (Hashing das Ergebnis von get()) sollte ausreichen. Nicht, wenn zwei Zeiger auf dasselbe Objekt nicht garantiert denselben Wert von get() zurückgeben, was in diesem speziellen Fall allgemein und plausibel ist.

+4

Die Hash-Funktion scheint explizit nicht mit der durch "owner_less" implizierten Gleichheit kompatibel zu sein, da der Hash explizit als Hash von 'get()'! –