2010-08-23 22 views
7

Todavía estoy trabajando en una buena solución para mi One-Of-A-Type Container Problem - y después de reflexionar creo que sería bueno poder usar algo como un std::map<std::type_info, boost::any>. Desafortunadamente, std::type_info no define un operator<, y creo que no sería razonable que definiera uno.¿C++ 11 proporciona funciones de hash para std :: type_info?

Sin embargo, parece razonable definir una función hash para ello, porque simplemente podría usar la dirección singleton del objeto std::type_info como un "hash" razonable. Por lo tanto, podría poner un std::type_info en un std::unordered_map como la clave.

¿C++ 11 proporciona una función hash? ¿Sería una mala estrategia hash usar la dirección de memoria del singleton std::type_info?

+2

No es un singleton, por cierto, sino un objeto estáticamente asignado. – GManNickG

+0

@GMan: ¿Cuál es la diferencia? –

+1

Si fuera un singleton, habría exactamente un objeto 'type_info'. Como hay varios tipos en un programa, debe haber más de un objeto 'type_info' en el programa. –

Respuesta

9

El hecho de que type_info no sea menos que comparable no es tanto un problema para usarlo como clave de mapa como el hecho de que type_info no se puede copiar. :-)

En C++ 03, type_info tiene una función de miembro before() que proporciona un pedido de objetos type_info.

en C++ 11, type_info tiene una hash_code() de función miembro (C++ 11 §18.7.1/7):

size_t hash_code() const throw(); 

Devuelve: un valor fi ed no especificada, excepto que dentro de una única ejecución del programa, devolverá el mismo valor para dos objetos type_info que se igualen.

Observación: una implementación debería devolver valores diferentes para dos objetos type_info que no son iguales. existen

type_info objetos resultantes del operador typeid hasta el final del programa, por lo que es seguro de usar un type_info* como una clave del mapa. Sin embargo, a mi leal saber y entender, no hay garantía de que si aplica typeid a dos objetos del mismo tipo, obtendrá dos referencias al mismo objeto type_info.

Si usted hace uso de type_info* como una clave del mapa, que haría uso de un comparador personalizado que elimina referencia a los punteros y compara la type_info propios objetos (usando la mencionada before() o hash_code() para el pedido).

+0

@James: D'oh! Quizás pueda usar 'std :: type_info *' (porque solo hay una instancia de una clase type_info en particular?)? –

+0

@Billy: Eso debería ser seguro (ver mi edición para advertencias). –

+0

@James: Eso podría ser difícil porque los objetos 'std :: type_info' no proporcionan una manera eficiente de compararse. Parece que ha vuelto a la solución de elaboración casera para mí:/ –

10

También puede usar type_index, sostiene de forma segura un puntero a un type_info, es copiable, comparable y se proporciona una función hash para contenedores estándar.