Ren*_*ter 95 c++ hash unordered-map unordered-set c++11
为了支持用户定义的键类型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;
Run Code Online (Sandbox Code Playgroud)
std::unordered_set<X>
使用类型的默认哈希来编写会更方便X,就像编译器和库中的类型一样.咨询后
include\c++\4.7.0\bits\functional_hash.h 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
}
Run Code Online (Sandbox Code Playgroud)
鉴于编译器对C++ 11的支持尚未实验 - 我没有尝试过Clang ---,这些是我的问题:
将这样的专业化添加到命名空间是否合法std?我对此感到复杂.
哪个std::hash<X>::operator()版本(如果有的话)符合C++ 11标准?
有可行的方法吗?
Ker*_* SB 121
您明确允许和鼓励增加特来命名std*.添加哈希函数的正确(也是基本上唯一的)方法是这样的:
namespace std {
template <> struct hash<Foo>
{
size_t operator()(const Foo & x) const
{
/* your code here, e.g. "return hash<int>()(x.value);" */
}
};
}
Run Code Online (Sandbox Code Playgroud)
(您可能考虑支持的其他流行专业是std::less,std::equal_to和std::swap.)
*)只要其中一个涉及的类型是用户定义的,我想.
我打赌将在unordered_map/unorder_set/...类的Hash模板参数上:
#include <unordered_set>
#include <functional>
struct X
{
int x, y;
std::size_t gethash() const { return (x*39)^y; }
};
typedef std::unordered_set<X, std::size_t(*)(const X&)> Xunset;
typedef std::unordered_set<X, std::function<std::size_t(const X&)> > Xunset2;
int main()
{
auto hashX = [](const X&x) { return x.gethash(); };
Xunset my_set (0, hashX);
Xunset2 my_set2(0, hashX); // if you prefer a more flexible set typedef
}
Run Code Online (Sandbox Code Playgroud)
当然
struct Xhasher { size_t operator(const X&) const; };)std::hash<X>()| 归档时间: |
|
| 查看次数: |
47268 次 |
| 最近记录: |