Il semble que C++ n'ait pas de fonction de hachage pour les chaînes dans la bibliothèque standard. Est-ce vrai?
Quel est un exemple pratique d'utilisation d'une chaîne comme clé dans un unordered_map qui fonctionnera avec n'importe quel compilateur c ++?
C++ STL fournit un modèle spécialisations of std::hash
pour les différentes classes de chaînes. Vous pouvez simplement spécifier std::string
comme type de clé pour std::unordered_map
:
#include <string>
#include <unordered_map>
int main()
{
std::unordered_map<std::string, int> map;
map["string"] = 10;
return 0;
}
J'ai rencontré ça aujourd'hui (en fait avec wstring
, pas string
, mais c'est la même chose): utiliser wstring
comme clé dans un unordered_map
génère une erreur indiquant qu'aucune fonction de hachage n'est disponible pour ce type.
La solution pour moi a été d'ajouter:
#include <string>
Croyez-le ou non, sans l'inclusion, j'avais toujours le type wstring disponible mais apparemment PAS les fonctions auxiliaires comme le hachage. L'ajout simple de l'inclusion ci-dessus l'a corrigé.
En fait, il y a std::hash<std::string>
Mais voici comment utiliser une autre fonction de hachage:
struct StringHasher {
size_t operator()(const std::string& t) const {
//calculate hash here.
}
}
unordered_map<std::string, ValueType, StringHasher>
Si vous avez un CustomType
et que vous souhaitez vous connecter à l'infrastructure STL, c'est ce que vous pourriez faire.
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 vous souhaitez ensuite créer disons un std::unordered_map<CustomType>
la STL trouvera les hash
et equal_to
fonctionne sans que vous ayez à faire plus avec le modèle. C'est ainsi que j'aime écrire mon comparateur d'égalité personnalisé qui prend en charge les structures de données non ordonnées.
Dans mon cas, c'était vraiment une distraction.
J'avais un type X pour lequel j'ai implémenté le hachage pour const & X an utilisé quelque part avec
std::unordered_map<const X, int> m_map;
Ensuite, je voulais avoir une autre carte dont les clés sont du type X
et j'ai fait:
std::unordered_map<X, int> map_x;
Notez le MANQUE de const
sur le deuxième cas.