2015-07-13 15 views
9

Używam zewnętrznej biblioteki sieciowej, która zwraca niektóre magiczne struktury reprezentujące otwarte gniazda, a dokumenty mówią, że podczas wstawiania ich do kontenerów STL, powinny być porównywane przy użyciu std::owner_less.C++ 11 unordered_set z std :: owner_less-like hashing

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

Jednak zamiast tego chciałbym użyć unordered_map. Jak mogę to zrobić? std::owner_less to komparator i nie ma sensu na mapie skrótu. Kopanie w kodzie źródłowym, MagicStructure wydaje się być typedef dla std::shared_ptr.

+0

To może być oryginalne pominięcie normy. Potrzebowalibyśmy czegoś takiego jak 'owner_equal' i' owner_hash'; ten ostatni może być hashem adresu bloku kontrolnego. –

+0

Można spojrzeć na kod źródłowy i sprawdzić, czy ustawiono deleter, a jeśli tak, jaki typ. Następnie spróbuj 'get_deleter'. Być może 'deleter' może być użyty jako proxy dla" właściciela ". – Yakk

Odpowiedz

2

Niestety, wydaje się, że trzeba użyć map, i nie może korzystać unordered_map dla takiego scenariusza: http://wg21.cmeerw.net/lwg/issue1406

Hash wsparcie dla własności oparte na relacji równoważności nie może być dostarczona przez czytelnymi zdefiniowany sposób, ponieważ informacje o podziale własności nie są w ogóle dostępne dla użytkowników. Dlatego jedynym sposobem na zapewnienie asocjacyjnej funkcji asocjacyjnej jest za pomocą standardowej biblioteki.

W Innymi słowy, nie jest przechowywany (zwrócony przez get()) i posiadał wskaźnik (który zostanie usunięty, gdy licznik odwołań osiągnie 0) w shared_ptr: http://www.cplusplus.com/reference/memory/shared_ptr/get/. Aby korzystać z posiadanego wskaźnika w postaci unordered_map, musisz posiadać operacje oparte na wskaźnikach oparte na hash() i equals(). Ale nie są one dostarczane w STL. I nie możesz ich samemu wdrożyć (bez ponownego wdrażania shared_ptr i zmiany definicji twojego MagicStructure), ponieważ posiadany wskaźnik nie jest udostępniony przez shared_ptr.

+1

http://en.cppreference.com/w/cpp/memory/shared_ptr/owner_before ma znaczenie, ponieważ wyjaśnia, w jaki sposób 'a.get() Yakk

0

Zamówienie z std::owner_less można łatwo dostosować do porównania równości (aib są równe, jeśli żaden nie poprzedza drugiego).

Domyślna implementacja mieszająca dla std::shared_ptr (mieszająca wynik get()) powinna wystarczyć. Nie, jeśli dwa wskaźniki do tego samego obiektu nie mają gwarancji, że zwrócą tę samą wartość z get(), co jest w ogóle możliwe i wiarygodne w tym konkretnym przypadku.

+4

Funkcja mieszania wydaje się być wyraźnie niezgodna z równością implikowaną przez 'owner_less', ponieważ skrót jest jawnie podany jako mieszanie' get() '! –

Powiązane problemy