¿Es necesario que cree mi propia función hash para tipos personalizados? ¿No hay valores predeterminados que pueda usar con unordered_set?Cómo usar unordered_set con tipos personalizados?
Respuesta
La biblioteca estándar contiene especializaciones de std::hash<T>
para los tipos fundamentales, para los punteros y para std::string
(o más bien, para todas las especializaciones de std::basic_string
).
Por desgracia, la biblioteca no no contener la siguiente función vital nueva a partir de edad combinación, que sin embargo es parte de Boost, y que se debe copiar en su código:
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
Con esta función, puede hash pares, tuplas, matrices y cualquier tipo de rango de elementos que son ellos mismos hashable. Explore las fuentes de Boost para obtener muchos ejemplos e implementaciones útiles. Y, obviamente, puede usar esta función para crear una función hash para sus propios tipos. Por ejemplo, aquí hay un par de hash:
template<typename S, typename T> struct pair_hash<std::pair<S, T>>
{
inline std::size_t operator()(const std::pair<S, T> & v) const
{
std::size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
return seed;
}
};
Por favor, tenga en cuenta, sin embargo, que la combinación de hash no produce buenos valores hash. Los resultados tienen cualidades estadísticas muy pobres (por ejemplo, es muy fácil crear colisiones hash). Un buen hashing necesita poder ver todos los bits de entrada sin procesar, y no se puede factorizar mediante hashes parciales. (Es por eso que no hay una solución mejor en la biblioteca estándar actual, nadie ha podido encontrar un diseño satisfactorio).
¿Cuál es la explicación para la línea clave de la función hash_combine: seed^= hasher (v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); –
No importa, encontré la respuesta aquí (http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine). –
Sí, tendrá que escribir su propia función hash. Esto no es tan malo como parece: si su clase tiene algún miembro hashable que sabe que será razonablemente único, puede simplemente devolver el hash de ese miembro.
Puede proporcionar este hash especializándose std::hash
, o pasando explícitamente la clase hash como parámetro de plantilla.
- 1. cómo agrupar por tipos personalizados con LINQ
- 2. Haskell: tipos personalizados con condiciones
- 3. Cómo usar sombreadores personalizados junto con GLKit
- 4. Cómo usar iconos personalizados con mapKit framework?
- 5. Cómo usar jQuery ¿Diferido con eventos personalizados?
- 6. cómo mostrar los datos personalizados de tipos de envíos personalizados
- 7. Migraciones de Doctrine, problemas al usar tipos de doctrina personalizados
- 8. android: ¿Cómo usar colores personalizados?
- 9. Inserción en tipos SQL personalizados con instrucciones preparadas en java
- 10. Tipos personalizados en el kernel OpenCL
- 11. ¿Crear tipos de mensajes personalizados en win32?
- 12. Agregando tipos de estructura personalizados a strace
- 13. nAsignación de hibernación a tipos personalizados
- 14. ¿Google Chrome admite tipos MIME personalizados?
- 15. Puede sobrecargar Suma para agregar tipos personalizados
- 16. Cómo usar Jugar con módulos personalizados y integración continua
- 17. ¿Cómo extender std :: tr1 :: hash para tipos personalizados?
- 18. Haskell: Derivado Mostrar de los tipos personalizados
- 19. ¿Cómo puedo definir una matriz de tipos personalizados en WSDL?
- 20. tr1 :: unordered_set unión e intersección
- 21. Usar la configuración con tipos complejos
- 22. Cómo usar controles personalizados en WPF
- 23. ¿Cómo usar permisos personalizados en Android?
- 24. cómo enumerar los tipos personalizados usando Postgres INFORMATION_SCHEMA
- 25. Al usar argparse, ¿debería ocurrir la validación y la inicialización en tipos o acciones personalizados?
- 26. Cómo usar objetos con xsi: tipos en Savon
- 27. ¿Cómo puedo usar tipos de retorno covariantes con punteros inteligentes?
- 28. ¿Cómo usar protobuf-net con tipos de valores inmutables?
- 29. ¿Cómo puedo usar Boost.Bind en tipos compuestos?
- 30. ICollection <T> .Contains sobre tipos personalizados
¿Cuál es la "forma predeterminada" de hash de un 'Foo'? –