Следующий код определяет 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
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
уменьшит вероятность столкновений.
Других решений пока нет …