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

发布于 2024-10-25 22:14:38 字数 443 浏览 1 评论 0原文

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

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

According to this, it is possible to define an equality function in a TR1 unordered_map like this:

#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;

Is it possible to define the hash function the same way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

临风闻羌笛 2024-11-01 22:14:38

如果您想要更改默认哈希(或者,更常见的是,为当前不支持的类型提供哈希),您可以提供 std::tr1::hash 的专门化您的键类型:

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

请注意,将现有模板专门用于用户定义类型是允许您在命名空间中编写代码的罕见情况之一标准。

If you want to change the default hashing (or, more often, provide hashing for a type that isn't currently supported), you provide a specialization of std::tr1::hash<T> for your key-type:

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

Note that specializing an existing template for a user-defined type is one of the rare cases where you specifically are allowed to write code in namespace std.

毁我热情 2024-11-01 22:14:38

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<> 默认情况下使用运算符 == 检查相等性。编译器找到您的 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();
        }
    };
}

The signature of the unordered_map class is this:

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;

Your example works because the default Pred, std::equal_to<>, by default checks for equality using operator==. The compiler finds your foo::operator== member function and uses that.

std::hash doesn't have any specialisation which will call a member function on your class, so you can't just add a member to foo with a custom hash. You will need to specialise std::hash instead. If you want that to call a member function on foo, go ahead. You'll end up with something like this:

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();
        }
    };
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文