如何为std :: string定义自定义std :: basic_string <>特化类的Hash类?

Lee*_*hai 8 c++ string hash c++14

我有一个专业化std::basic_string,比如说string_t,它的相同std::string不同之处在于第三个模板参数是我的自定义分配器.

的std :: basic_string的<>

问题:如何使用C++标准库中已提供的散列函数为此专门化定义散列函数类?

我知道如何定义一个Hash仿函数,但我不知道如何利用现有的std::hash<..>仿函数std来定义我的自定义仿函数.我毫不犹豫地写我自己的哈希运算,知道它是重新发明轮子,是不太可能优于std::hash<std::string>,因为之间的唯一区别string_t,并std::string仅仅是分配器.

cppreference有一些例子,但它们对我没有多大帮助 - 我不想std::string使用我的string_t对象的c_str()方法构造一个临时对象,只是std::hash<std::string>为了获取哈希值而将临时对象提供给它,因为它需要分配临时堆内存.

我正在使用C++ 14,我想坚持使用标准库.

Ric*_*ges 5

问题:我应该如何使用 C++ 标准库中已提供的哈希函子来为此专门化定义哈希函子类?

简短而悲伤的答案是没有办法做到这一点。标准库不提供整数类型序列的哈希函数。

解决方法:

boost::hash在各方面都优于std::hash. 我建议你std::hash根据它来定义你的专业。

此外,如果可以的话,指定boost::hash<>为所有无序容器的哈希函数。你永远不会后悔。std::hash是一个半成型的图书馆。

#include <string>
#include <cassert>
#include <unordered_set>
#include <boost/functional/hash.hpp>

struct my_alloc ...

using my_string = std::basic_string<char, std::char_traits<char>, my_alloc>;
std::size_t hash_value(::my_string const& s)
{
            return boost::hash_range(s.begin(), s.end());
}

namespace std {
    template<> struct hash<::my_string> 
    {
        std::size_t operator()(::my_string const& s) const
        {
            return hash_value(s);
        }
    };
}

int main()
{
    auto x = my_string("Hello");

    using Set1 = std::unordered_set<my_string, boost::hash<my_string>>;
    auto set1 = Set1 { x };

    auto h = std::hash<my_string>();
    auto hh = h(x);
    assert(hh == hash_value(x));
    return int(hh);
}
Run Code Online (Sandbox Code Playgroud)