Defining a hash function in TR1 unordered_map inside a struct

£可爱£侵袭症+ 提交于 2019-12-03 03:48:55

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.

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();
        }
    };
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!