Pour prendre en charge les types de clés définis par l'utilisateur dans std::unordered_set<Key>
et std::unordered_map<Key, Value>
il faut fournir operator==(Key, Key)
un foncteur de hachage:
struct X { int id; /* ... */ };
bool operator==(X a, X b) { return a.id == b.id; }
struct MyHash {
size_t operator()(const X& x) const { return std::hash<int>()(x.id); }
};
std::unordered_set<X, MyHash> s;
Il serait plus pratique d'écrire uniquement std::unordered_set<X>
avec un hachage par défaut pour le type X
, comme pour les types accompagnant le compilateur et la bibliothèque. Après consultation
- Projet de norme C ++ N3242 §20.8.12 [unord.hash] et §17.6.3.4 [hash.requirements],
- Boost.
- g ++
include\c++\4.7.0\bits\functional_hash.h
- VC10
include\xfunctional
- diverses questions connexes dans Stack Overflow
il semble possible de se spécialiser std::hash<X>::operator()
:
namespace std { // argh!
template <>
inline size_t
hash<X>::operator()(const X& x) const { return hash<int>()(x.id); } // works for MS VC10, but not for g++
// or
// hash<X>::operator()(X x) const { return hash<int>()(x.id); } // works for g++ 4.7, but not for VC10
}
Étant donné que le support du compilateur pour C ++ 11 est encore expérimental --- je n'ai pas essayé Clang ---, voici mes questions:
Est-il légal d'ajouter une telle spécialisation à l'espace de noms
std
? J'ai des sentiments mitigés sur ce sujet.Laquelle des
std::hash<X>::operator()
versions, le cas échéant, est conforme à la norme C ++ 11?Existe-t-il un moyen portable de le faire?
std::hash
(contrairement à d'autres choses dans l' std
espace de noms) est déconseillée par le guide de style de Google ; Prenez-le avec un grain de sel.
operator==(const Key, const Key)