【问题标题】:using lambda do define hash function throws exception使用 lambda 定义哈希函数会引发异常
【发布时间】:2013-01-28 06:56:41
【问题描述】:

以下代码定义了一个unordered_set。 代码编译得很好。 但是在调用 find 时使用 lambda 函数而不是 functor throw:

libc++abi.dylib:终止调用抛出异常

#include <unordered_set>

class pair_hash {
    public:
        size_t operator() (const std::pair<int, int> &x) const {
            return std::hash<int>()(x.first) ^ std::hash<int>()(x.second);
        }
};

int main() {
    std::unordered_set<std::pair<int, int>, pair_hash> temp;
    temp.find(std::make_pair(0,0));


    std::function<std::size_t(std::pair<int , int>)> fpair_hash;
    fpair_hash = [](const std::pair<int, int>& v) -> std::size_t
    {
        return std::hash<int>()(v.first) ^ std::hash<int>()(v.second);
    };

    std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2;
    //why does this not work?
    temp2.find(std::make_pair(0,0));
    return 0;
}

clang++ -std=c++11 -stdlib=libc++ -o test test.cpp

【问题讨论】:

    标签: c++ hash c++11 std unordered-set


    【解决方案1】:

    decltype(fpair_hash)std::function&lt;std::size_t(std::pair&lt;int , int&gt;)&gt;,所以你只是在使用空哈希函数构建集合。

    你需要将你的函数提供给std::unordered_set的构造函数:

    std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2(10, fpair_hash);
    

    这应该可以正常工作,但是使用 std::function 会产生多态调用的开销,您可能不需要它:

    auto fpair_hash = [](const std::pair<int, int>& v) -> std::size_t
    {
        return std::hash<int>()(v.first) ^ std::hash<int>()(v.second);
    };
    

    最后,你的散列函数不是很好——它将所有对 (x, x) 映射到 0。也许使用类似x * 17 + y * 13 而不是x ^ y 会降低冲突的可能性。

    【讨论】:

    • 我支持return std::hash&lt;int&gt;()(std::hash&lt;int&gt;()(v.first) ^ v.second);
    猜你喜欢
    • 2016-09-22
    • 2011-09-11
    • 2012-01-07
    • 2012-01-13
    • 2012-07-23
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多