Benutzerdefinierte Schlüsseltypen in zu unterstützen std::unordered_set<Key>
und std::unordered_map<Key, Value>
man hat zu schaffen operator==(Key, Key)
und ein Hash Funktors:
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;
Es wäre bequemer, nur std::unordered_set<X>
mit einem Standard-Hash für Typ zu schreiben X
, wie für Typen, die mit dem Compiler und der Bibliothek geliefert werden. Nach Rücksprache mit
- C ++ Standard Draft N3242 §20.8.12 [unord.hash] und §17.6.3.4 [hash.requirements],
- Boost.Unordered
- g ++
include\c++\4.7.0\bits\functional_hash.h
- VC10
include\xfunctional
- verschiedene verwandte Fragen im Stapelüberlauf
es scheint möglich zu spezialisieren 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
}
Angesichts der Tatsache, dass die Compiler-Unterstützung für C ++ 11 noch experimentell ist - ich habe Clang nicht ausprobiert -, sind dies meine Fragen:
Ist es legal, dem Namespace eine solche Spezialisierung hinzuzufügen
std
? Ich habe gemischte Gefühle.Welche der
std::hash<X>::operator()
Versionen entspricht gegebenenfalls dem C ++ 11-Standard?Gibt es eine tragbare Möglichkeit, dies zu tun?
std::hash
(im Gegensatz zu anderen Dingen im std
Namespace) vom Google Style Guide nicht empfohlen wird. nimm es mit einem Körnchen Salz.
operator==(const Key, const Key)