используя лямбду, определите хеш-функцию

Следующий код определяет unordered_set,
Код компилируется просто отлично.
Но используя лямбда-функцию вместо functor throw при вызове find:

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

1

Решение

decltype(fpair_hash) является std::function<std::size_t(std::pair<int , int>)> так что вы просто строите набор с пустой хэш-функцией.

Вы должны предоставить свою функцию конструктору 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 уменьшит вероятность столкновений.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]