在结构内部的TR1 unordered_map中定义哈希函数

时间:2011-03-25 15:21:14

标签: c++ hash tr1 unordered-map

根据this,可以在TR1 unordered_map中定义一个相等函数,如下所示:

#include <tr1/unordered_map>
using namespace std;
using namespace std::tr1;
struct foo{
    ...
    bool operator==(const foo& b) const{
        return ..;
    }
};

unordered_map<foo,int> map;

是否可以用相同的方式定义哈希函数?

2 个答案:

答案 0 :(得分:12)

如果要更改默认哈希(或者更常见的是,为当前不支持的类型提供哈希),则为密钥类型提供std::tr1::hash<T>的特化:

namespace std { 
namespace tr1 { 
    template<>
    struct hash<typename my_key_type> {
        std::size_t operator()(my_key_type const &key) {
            return whatever;
        }
    };
}
}

请注意,为用户定义的类型专门化现有模板是罕见的案例之一,您可以 允许在namespace std中编写代码。

答案 1 :(得分:1)

unordered_map类的签名是:

template<class Key,
    class Ty,
    class Hash = std::hash<Key>,
    class Pred = std::equal_to<Key>,
    class Alloc = std::allocator<std::pair<const Key, Ty> > >
    class unordered_map;

您的示例有效,因为默认的Pred,std :: equal_to&lt;&gt;,默认使用operator ==检查相等性。编译器找到你的foo :: operator == member函数并使用它。

std :: hash没有任何可以在您的类上调用成员函数的特化,因此您不能仅使用自定义哈希向foo添加成员。您将需要专门化std :: hash。如果你想在foo上调用成员函数,请继续。你最终会得到这样的东西:

struct foo
{
    size_t hash() const
    {
       // hashing method here, return a size_t
    }
};

namespace std
{
    // Specialise std::hash for foo.
    template<>
    class hash< foo >
        : public unary_function< foo, size_t >
    {
    public:
        size_t operator()( const foo& f )
        {
            return f.hash();
        }
    };
}