int main(int argc, const char * argv[]) {
function<bool(vector<int>&,vector<int>&)> cmp=[](vector<int>&a,vector<int>&b)->bool{
return a[0]>b[0];
};
priority_queue<vector<int>,vector<vector<int>>,decltype(cmp)> q(cmp); //Fine
function<size_t(pair<int, int>&)> pair_hash = [](pair<int, int>& p) -> size_t {
return hash<int>()(p.first) ^ hash<int>()(p.second);
};
unordered_set<pair<int, int>, decltype(pair_hash)> blocks(pair_hash); //Error
}
I wonder why unordered_set
can not use a lambda expression for a customized hash function.
At first I use this:
struct pair_hash {
template <class T1, class T2>
size_t operator () (pair<T1, T2> const &pair) const
{
size_t h1 = hash<T1>()(pair.first);
size_t h2 = hash<T2>()(pair.second);
return h1 ^ h2;
}
};
unordered_set<pair<int,int>, pair_hash> blocks; //Fine
The above code run well. So I wanted to convert it to a lambda expression. But I failed. I just want to know how to write a proper lambda expression about pair<int,int>
hash function for unordered_set
.
So std::unordered_set
does not have a matching constructor for what you are trying to do.
You need to add an additional argument to blocks to specify the size of the set, i.e. the bucket_count: https://en.cppreference.com/w/cpp/container/unordered_set/unordered_set
Like this:
std::unordered_set<std::pair<int, int>, decltype(pair_hash)> blocks(3, pair_hash);
Also, I don't think this is a lambda expression:
function<size_t(pair<int, int>&)> pair_hash = [](pair<int, int>& p) -> size_t {
return hash<int>()(p.first) ^ hash<int>()(p.second);
};
You create a lambda expression, but then assign it to a std::function
type object.
I wonder if this works instead:
auto pair_hash = [](pair<int, int>& p) -> size_t {
return hash<int>()(p.first) ^ hash<int>()(p.second);
};
Additionally, this function is not the same, since it takes a const &
as a parameter. Perhaps you need to add a const
qualification to your lambda?:
size_t operator () (pair<T1, T2> const &pair) const
{
size_t h1 = hash<T1>()(pair.first);
size_t h2 = hash<T2>()(pair.second);
return h1 ^ h2;
}