2015-07-13 13 views
9

Sto usando una libreria di rete esterna che restituisce alcune strutture magiche che rappresentano socket aperti e i documenti dicono che quando li si inserisce in contenitori STL, devono essere confrontati usando std::owner_less.C++ 11 unordered_set con std :: owner_less-like hashing

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

Tuttavia mi piacerebbe utilizzare unordered_map invece. Come posso farlo? std::owner_less è un comparatore ed è inutile per una mappa hash. Digitando il codice sorgente, MagicStructure sembra un typedef per std::shared_ptr.

+0

Questa potrebbe essere una vera e propria omissione dallo standard. Avremmo bisogno di qualcosa come 'owner_equal' e' owner_hash'; quest'ultimo potrebbe essere l'hash dell'indirizzo del blocco di controllo. –

+0

Si potrebbe guardare il codice sorgente e vedere se impostano un deleter e, in caso affermativo, di quale tipo. Quindi prova 'get_deleter'. Probabilmente il 'deleter' può essere usato come proxy per il" proprietario ". – Yakk

risposta

2

Purtroppo, sembra che si deve utilizzare un map, e non è possibile utilizzare unordered_map per tale scenario: http://wg21.cmeerw.net/lwg/issue1406

sostegno Hash per la relazione di equivalenza di proprietà basata non possono essere forniti da qualsiasi dall'utente modo definito perché le informazioni sulla condivisione della proprietà non sono disponibili per gli utenti. Pertanto, l'unico modo per fornire un supporto hash proprietario basato su proprietà è di offrire intrusivamente dalla libreria standard.

Nelle altre parole, non è memorizzato (restituito da get()) e di proprietà puntatore (che viene eliminata quando conteggio di riferimento raggiunge 0) in un shared_ptr: http://www.cplusplus.com/reference/memory/shared_ptr/get/. Per utilizzare il puntatore proprietario in un unordered_map, è necessario il puntatore di proprietà basato sulle operazioni hash() e equals(). Ma non sono forniti in STL. E non è possibile implementarli da soli (senza reimplementare shared_ptr e modificare la definizione del proprio MagicStructure) perché il puntatore di proprietà non è esposto da shared_ptr.

+1

http://en.cppreference.com/w/cpp/memory/shared_ptr/owner_before è rilevante, in quanto rende più chiaro come 'a.get() Yakk

0

L'ordine da std::owner_less può essere facilmente adattato in un confronto di uguaglianza (aeb sono uguali se nessuno dei due precede l'altro).

L'implementazione di hashing predefinita per std::shared_ptr (con il risultato di get()) dovrebbe essere sufficiente. Non è possibile che due puntatori allo stesso oggetto restituiscano lo stesso valore da get(), che è possibile in generale e plausibile in questo caso particolare.

+4

La funzione di hash sembra essere esplicitamente non compatibile con l'uguaglianza implicita da 'owner_less', poiché l'hash è esplicitamente indicato come hash di' get() '! –

Problemi correlati