I wonder if it is possible to use lambda function as custom hash function for unordered_map in C++11? If so, what is the syntax?
-
What have you tried? Just need to pass the lambda, or a variable that holds a lambdaAjay– Ajay2013-03-30 13:34:37 +00:00Commented Mar 30, 2013 at 13:34
-
@Ajay, I tried, but some weird errors always occurs...now I know how to do it...HanXu– HanXu2013-04-01 04:34:55 +00:00Commented Apr 1, 2013 at 4:34
Add a comment
|
2 Answers
#include<unordered_map>
#include<string>
int main() {
auto my_hash = [](std::string const& foo) {
return std::hash<std::string>()(foo);
};
std::unordered_map<std::string, int, decltype(my_hash)> my_map(10, my_hash);
}
You need to pass lambda object to unordered_map constructor, since lambda types are not default constructible.
As @mmocny suggested in comment, it's also possible to define make function to enable type deduction if you really want to get rid of decltype:
#include<unordered_map>
#include<string>
template<
class Key,
class T,
class Hash = std::hash<Key>
// skipped EqualTo and Allocator for simplicity
>
std::unordered_map<Key, T, Hash> make_unordered_map(
typename std::unordered_map<Key, T, Hash>::size_type bucket_count = 10,
const Hash& hash = Hash()) {
return std::unordered_map<Key, T, Hash>(bucket_count, hash);
}
int main() {
auto my_map = make_unordered_map<std::string, int>(10,
[](std::string const& foo) {
return std::hash<std::string>()(foo);
});
}
1 Comment
mmocny
Or, write a make_unordered_hash templated function for type deduction. There is also actually a C++ proposal to more generally address this problem isocpp.org/files/papers/n3602.html
Since C++20 stateless lambdas can be used in unevaluated contexts. Which means you can directly pass it with decltype, without declaring and initializing any variable like this:
unordered_set<int, decltype([](auto const& foo) {...})> container;
or with type alias (which may help to avoid some code duplication for example):
using hash_lambda = decltype([](auto const& foo){...});
unordered_set<int, hash_lambda> container;