4

据此可以在 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;

是否可以以相同的方式定义散列函数?

4

2 回答 2

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.

于 2011-03-25T15:47:19.267 回答
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<>,默认情况下使用 operator== 检查相等性。编译器找到您的 foo::operator== 成员函数并使用它。

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();
        }
    };
}
于 2011-03-25T15:50:42.013 回答