Для поддержки пользовательских типов ключей в std::unordered_set<Key>
и std::unordered_map<Key, Value>
нужно предоставить operator==(Key, Key)
и функтор хеширования:
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;
Было бы удобнее писать только std::unordered_set<X>
с хешем по умолчанию для типа X
,
как для типов, входящих вместе с компилятором и библиотекой.
После консультации
- С++ Standard Проект N3242 §20.8.12 [unord.hash] и §17.6.3.4 [hash.requirements],
- Boost.Unordered
- g++
include\c++\4.7.0\bits\functional_hash.h
- VC10
include\xfunctional
- различные связанные вопросы в переполнении стека
представляется возможным специализировать 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
}
Предоставление поддержки компилятора для С++ 11 еще экспериментально --- я не пробовал Clang ---, это мои вопросы:
-
Можно ли добавить такую специализацию в пространство имен
std
? У меня смешанные чувства по этому поводу. -
Какая из версий
std::hash<X>::operator()
, если таковая имеется, соответствует стандарту С++ 11? -
Есть ли способ передвижения?