The following code defines a unordered_set. The code compiles just fine. But using the lambda function instead of functor throw when calling find:

libc++abi.dylib: terminate called throwing an exception

#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

有帮助吗?

解决方案

decltype(fpair_hash) is std::function<std::size_t(std::pair<int , int>)> so you are just building set with empty hash function.

You need to provide your function to constructor of std::unordered_set:

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

This should make it work, but using std::function will have overhead of polymorphic call and you probably don't need it:

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

Finally, your hash function is not really good - it maps all pairs (x, x) to 0. Perhaps using something like x * 17 + y * 13 instead of x ^ y will reduce probability of collisions.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top