问题
Trying to override map::compare
function using lambda, it seems that the following solution works.
auto cmp = [](const int&a, const int& b) { return a < b; };
std::map<int, int, decltype(cmp)> myMap(cmp);
But, I had to define cmp
first and use it later.
Can I do this without defining 'cmp'?
回答1:
No, you can't use lambda in unevaluated context -- i.e. template parameters as in your example.
So you must define it somewhere else (using auto
) and then use decltype
... the other way, as it was mentioned already is to use an "ordinal" functors
If your question is about "how to use lambda expression *once* when define a map" you can exploit implicit conversion of lambdas to std::function
like this:
#include <iostream>
#include <functional>
#include <map>
int main()
{
auto m = std::map<int, int, std::function<bool(const int&, const int&)>>{
[](const int& a, const int& b)
{
return a < b;
}
};
return 0;
}
you may introduce an alias for that map
type to reduce typing later...
回答2:
#include <iostream>
#include <functional>
#include <map>
#include <typeinfo>
typedef std::map< int, int, std::function<bool(const int&, const int&)> > MyMap;
int main()
{
auto cmp = [](const int& a, const int& b) { return a < b; };
MyMap map(cmp);
return 0;
}
Using std::function
to provide the appropriate type signature for the comparator type you can define your map type and then assign any lambda compare you wish to.
回答3:
You could do something like this where the type of the map is deduced from the function you pass to a function.
#include <map>
template<class Key, class Value, class F>
std::map<Key, Value, F> make_map(const F& f) {
return std::map<Key, Value, F>{f};
}
int main() {
auto my_map = make_map<int, int>([](const int&a, const int& b) { return a < b; });
my_map[10] = 20;
}
I don't see a ton of reason for doing this but I wont say it's useless. Generally you want a known comparator so that the map can be passed around easily. With the setup above you are reduced to using template functions all the time like the following
tempalte<class F>
void do_somthing(const std::map<int, int, F>& m) {
}
This isn't necessarily bad but my instincts tell me that having a type which can ONLY be dealt with by generic functions is bad. I think it works out fine for lambda functions but that's about it. The solution here is to use std::function
#include <map>
#include <functional>
template<class Key, class Value>
using my_map_t = std::map<Key, Value, std::function<bool(const Key&, const Key&)>>;
int main() {
my_map_t<int, int> my_map{[](const int&a, const int& b) { return a < b; }};
my_map[10] = 20;
}
Now you can use any predicate you want and you have a concrete type to work with, my_map
hope this helps!
来源:https://stackoverflow.com/questions/18045208/override-mapcompare-with-lambda-function-directly