À l'appui de touche définie par l'utilisateur des types en std::unordered_set<Key>
et std::unordered_map<Key, Value>
on a à offrir operator==(Key, Key)
et un hachage foncteur:
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 commode d'écrire juste std::unordered_set<X>
avec un hachage par défaut pour le type X
,
comme pour les types à venir avec le compilateur et de la bibliothèque.
Après consultation de
- Norme C++ Projet de N3242 §20.8.12 [unord.hash] et §17.6.3.4 [hachage.exigences],
- Coup de pouce.Non ordonnée
- g++
include\c++\4.7.0\bits\functional_hash.h
- VC10
include\xfunctional
- divers liés à la questions dans le Débordement de Pile
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
}
Compte tenu de prise en charge du compilateur de C++11 est encore expérimental---je n'ai pas essayer Clang---, voici mes questions:
Est-il légal d'ajouter une spécialisation à l'espace de noms
std
? J'ai des sentiments mitigés à ce sujet.Qui de la
std::hash<X>::operator()
versions, le cas échéant, est compatible avec le C++11?Est-il un portable moyen de le faire?