2010-08-23 9 views
7

Sto ancora lavorando a una buona soluzione per il mio One-Of-A-Type Container Problem - e su riflessione penso che sarebbe bello poter usare solo qualcosa come un std::map<std::type_info, boost::any>. Sfortunatamente, std::type_info non definisce uno operator< e penso che sarebbe irragionevole definirlo.Il C++ 11 fornisce funzioni di hashing per std :: type_info?

Tuttavia, sembra ragionevole definire una funzione di hash per esso, poiché è possibile utilizzare semplicemente l'indirizzo singleton dell'oggetto std::type_info come un "hash" ragionevole. Pertanto, potresti inserire unoin uno std::unordered_map come chiave.

Il C++ 11 fornisce tale funzione hash? L'uso dell'indirizzo di memoria del singleton std::type_info sarebbe una brutta strategia di hash?

+2

Non è un singleton, a proposito, ma un oggetto assegnato staticamente. – GManNickG

+0

@GMan: Qual è la differenza? –

+1

Se fosse un singleton, ci sarebbe esattamente un oggetto 'type_info'. Dato che ci sono più tipi in un programma, ci deve essere più di un oggetto 'type_info' nel programma. –

risposta

9

Il fatto che type_info non sia inferiore a quello paragonabile non è tanto un problema per utilizzarlo come chiave di mappa quanto il fatto che type_info non è copiabile. :-)

In C++ 03, type_info ha una funzione membro before() che fornisce un ordinamento di oggetti type_info.

In C++ 11, type_info ha un hash_code() funzioni membro (C++ 11 §18.7.1/7):

size_t hash_code() const throw(); 

Reso: un valore fi cato non specificata, salvo che in un esecuzione singola del programma, deve restituire lo stesso valore per qualsiasi due oggetti type_info che si equivalgono.

Nota: un'implementazione deve restituire valori diversi per due type_info oggetti che non risultano uguali. Esistono

type_info oggetti risultanti dall'operatore typeid fino alla fine del programma, quindi è sicuro da usare un type_info* come chiave mappa. Tuttavia, per quanto a mia conoscenza, non vi è alcuna garanzia che se si applica typeid a due oggetti dello stesso tipo si otterranno due riferimenti allo stesso oggetto type_info.

Se si utilizza type_info* come chiave mappa, mi piacerebbe utilizzare un comparatore personalizzato che dereferenzia i puntatori e confronta il type_info stessi oggetti (usando il suddetto before() o hash_code() per l'ordinazione).

+0

@James: D'oh! Forse posso usare 'std :: type_info *' (perché c'è una sola istanza di una particolare classe type_info?)? –

+0

@Billy: Questo dovrebbe essere sicuro (vedi la mia modifica per i caveat). –

+0

@James: Potrebbe essere difficile perché gli oggetti 'std :: type_info' non forniscono un modo efficace per confrontarsi. Sembra che sia tornato alla soluzione di fermentazione domestica per me:/ –

10

È inoltre possibile utilizzare type_index, in modo sicuro contiene un puntatore a un type_info, è copiabile, confrontabile e una funzione di hash viene fornita per contenitori standard.