unordered_set unordered_map example c++ string c++11 key unordered-map

unordered_set - unordered_map c++ example



FunciĆ³n Hash C++ para cadena en unordered_map (5)

C ++ STL proporciona specializations de plantillas de std::hash para las diversas clases de cadenas. Solo podría especificar std::string como tipo de clave para std::unordered_map :

#include <string> #include <unordered_map> int main() { std::unordered_map<std::string, int> map; map["string"] = 10; return 0; }

Parece que C ++ no tiene una función hash para cadenas en la biblioteca estándar. ¿Es esto cierto?

¿Cuál es un ejemplo práctico de utilizar una cadena como clave en un mapa desordenado que funcionará con cualquier compilador de c ++?


En mi caso, fue realmente una distracción.

Tenía un tipo X para el que implementé el hashing para const & X y lo utilicé en alguna parte con

std::unordered_map<const X, int> m_map;

Luego quería tener otro mapa cuyas claves son del tipo X y lo hicieron:

std::unordered_map<X, int> map_x;

Observe la FALTA de const en el segundo caso.


En realidad, hay std::hash<std::string>

Pero ahí está cómo puedes usar otra función hash:

struct StringHasher { size_t operator()(const std::string& t) const { //calculate hash here. } } unordered_map<std::string, ValueType, StringHasher>


Me encontré con esto hoy (en realidad con wstring , no con string , pero es el mismo trato): el uso de wstring como clave en unordered_map genera un error sobre la ausencia de función hash disponible para ese tipo.

La solución para mí fue agregar:

#include <string>

Lo creas o no, sin el include todavía tenía el tipo de wstring disponible pero aparentemente NO las funciones auxiliares como el hash. Simplemente agregando el include de arriba lo solucionó.


Si tiene un CustomType y desea conectarse a la infraestructura de STL, esto es lo que podría hacer.

namespace std { //namespace tr1 //{ // Specializations for unordered containers template <> struct hash<CustomType> : public unary_function<CustomType, size_t> { size_t operator()(const CustomType& value) const { return 0; } }; //} // namespace tr1 template <> struct equal_to<CustomType> : public unary_function<CustomType, bool> { bool operator()(const CustomType& x, const CustomType& y) const { return false; } }; } // namespace std

Si luego quieres crear say a std::unordered_map<CustomType> el STL encontrará las funciones hash e equal_to sin que tengas que hacer nada más con la plantilla. Así es como me gusta escribir mi comparador de igualdad personalizado que admite estructuras de datos desordenadas.