我需要定义一个像unordered_map<pair<int, int>, *Foo>
这样的unordered_map,定义hash
和equal
函数并将其传递给此地图的语法是什么?
我已尝试将此对象传递给它:
class pairHash{
public:
long operator()(const pair<int, int> &k) const{
return k.first * 100 + k.second;
}
};
没有运气:
unordered_map<pair<int, int>, int> map = unordered_map<pair<int, int>, int>(1,
*(new pairHash()));
我不知道size_type_Buskets
的含义是什么,所以我给了它1
。
做正确的方法是什么?
感谢。
答案 0 :(得分:44)
这是C ++ 11中遗漏的一个遗漏; Boost在hash_combine
方面有答案。随意粘贴它们!这是我如何散列对:
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std
{
template<typename S, typename T> struct hash<pair<S, T>>
{
inline size_t operator()(const pair<S, T> & v) const
{
size_t seed = 0;
::hash_combine(seed, v.first);
::hash_combine(seed, v.second);
return seed;
}
};
}
您可以使用hash_combine
作为许多其他内容的基础,例如元组和范围,因此您可以散列整个(有序)容器,例如,只要每个成员都可以单独清洗。
现在你可以宣布一张新地图:
std::unordered_map<std::pair<int, int>, my_mapped_type> mymap;
如果你想使用自制的哈希(它没有很好的统计属性),你必须明确指定模板参数:
std::unordered_map<std::pair<int,int>, int, pairHash> yourmap;
请注意,无需指定hasher对象的副本,因为默认情况下是为您构造一个。
答案 1 :(得分:10)
如果你使用Boost就可以了,一个更干净的解决方案就是依靠Boost对对的哈希函数的实现(实际上这正是kerrek-sb在他的回答中解释的)。因此,您所要做的就是:
#include <unordered_map>
#include <boost/functional/hash.hpp>
using namespace std;
using namespace boost;
unordered_map<pair<int, int>, int, hash<pair<int, int>>> table;
答案 2 :(得分:9)
哈希函数的返回类型应为size_t
,而不是long
(尽管这不是错误的原因)。您为提供自定义哈希函数而显示的语法不正确。
您还需要提供一个相等的谓词来使上述工作正常。
#include <unordered_map>
#include <utility>
using namespace std;
class pairHash{
public:
size_t operator()(const pair<int, int> &k) const{
return k.first * 100 + k.second;
}
};
struct pairEquals : binary_function<const pair<int,int>&, const pair<int,int>&, bool> {
result_type operator()( first_argument_type lhs, second_argument_type rhs ) const
{
return (lhs.first == rhs.first) && (lhs.second == rhs.second);
}
};
int main()
{
unordered_map<pair<int, int>, int, pairHash, pairEquals> myMap;
myMap[make_pair(10,20)] = 100;
myMap.insert( make_pair(make_pair(100,200), 1000) );
}
修改强>
您不需要定义相等的谓词,因为为operator==
定义了std::pair
,它确实完成了我在pairEquals
中所做的工作。如果您希望以不同方式进行比较,则只需要pairEquals
定义。