C++ 无序映射散列函数c++;

C++ 无序映射散列函数c++;,c++,unordered-map,hash-function,C++,Unordered Map,Hash Function,我需要像这样定义一个无序映射无序映射,定义和传递散列和相等函数到此映射的语法是什么 我已尝试将此对象传递给它: class pairHash{ public: long operator()(const pair<int, int> &k) const{ return k.first * 100 + k.second; } }; 类pairHash{ 公众: 长运算符()(常量对和k)常量{ 返回k.first*100+k.second; }

我需要像这样定义一个无序映射
无序映射
,定义和传递
散列
相等
函数到此映射的语法是什么

我已尝试将此对象传递给它:

class pairHash{
public:
    long operator()(const pair<int, int> &k) const{
        return k.first * 100 + k.second;
    }
};
类pairHash{ 公众: 长运算符()(常量对和k)常量{ 返回k.first*100+k.second; } }; 没有运气:

unordered_map<pair<int, int>, int> map = unordered_map<pair<int, int>, int>(1,
*(new pairHash()));
无序地图=无序地图(1, *(新pairHash()); 我不知道
size\u type\u Buskets
是什么意思,所以我给了它
1
。 正确的方法是什么?
谢谢。

这在C++11中是一个不幸的遗漏;Boost的答案是
hash\u 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;
    }
  };
}

如果要使用自制哈希程序(没有良好的统计特性),必须明确指定模板参数:

std::unordered_map<std::pair<int,int>, int, pairHash> yourmap;
std::无序的地图;

请注意,无需指定哈希对象的副本,因为默认情况下是为您默认构造一个哈希对象。

哈希函数的返回类型应为
size\u 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) );
}
#包括
#包括
使用名称空间std;
pairHash类{
公众:
size\u t运算符()(常数对和k)常数{
返回k.first*100+k.second;
}
};
结构pairEquals:二进制函数{
结果类型运算符()(第一个参数类型lhs,第二个参数类型rhs)常量
{
返回(lhs.first==rhs.first)&&(lhs.second==rhs.second);
}
};     
int main()
{
无序的"我的地图",;
myMap[make_-pair(10,20)]=100;
插入(make_对(make_对(100200),1000));
}
编辑:

您不需要定义相等谓词,因为
operator==
是为
std::pair
定义的,它与我在
pairEquals
中所做的完全相同。如果您希望以不同的方式进行比较,则只需要使用
pairEquals
定义。

如果您对使用Boost没问题,一个更干净的解决方案是依赖Boost对pairs的哈希函数的实现(实际上这正是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;
#包括
#包括
使用名称空间std;
使用名称空间boost;
无序映射表;

@Vlad:Hmm。。。好的,使用pairhash专门化,您可以只编写
std::unordered\u映射并且不再担心。。。如果你真的想要一个命名的hasher,你必须指定所有四个模板参数,
。哇,简单点:-)检查我之前的评论:如果你想指定你自己的hasher类,你必须显式地命名所有四个模板参数,而你没有这样做。我添加了一行说明如何执行该操作。@Kerrek SB如果4个模板参数的顺序错误,则equal谓词将跟随hasher。另外,我比我所发布的更喜欢这个方法,但也许Vlad必须使用这个自定义哈希函数。@Praetorian:Ohh,谢谢你,多傻啊——在这种情况下,它更容易,因为你根本不需要列出第四个参数。@Kerrek SB不,你似乎不需要。我不知道有一个
操作符==
std::pair
*(new pairHash())
定义,谁要删除这个?你为什么在这里做动态分配?只需使用
pairHash()
。默认情况下已经定义了对的相等,字典排序也是如此。。。这确实是一个非常方便的小类:-)二进制函数似乎被禁止为C++ 11——一个很好的解决方案,但是我不会使用命名空间。我会把它写出来。这里很重要的一点是什么来自哪个名称空间。我也非常欣赏这个答案,我不确定顶部的答案是否应该被认为是一个好的实践。定义此类自制助手函数只会污染代码imho。
#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;