Override map :: compare with lambda function directly

Trying to override the map::compare function using lambda, the following solution seems to work.

 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"?

+6
source share
3 answers

No, you cannot use lambda in an unreasonable context - i.e. template options, as in your example. So you have to define it somewhere else (using auto ) and then use decltype ... another way, as mentioned, is to use ordinal functors

If your question is " how to use a lambda expression * once * when defining a map ), you can use the implicit conversion of lambdas to std::function as follows:

 #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 can enter an alias for this type of map to reduce typing later ...

+12
source
 #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 comparison you want.

+6
source

You can do something like this when the type of map is inferred from the function you pass to the 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 do not see the point in this, but I will not say that it is useless. Typically, you need a well-known comparator to easily carry the card. With the above setting, you always turn off using the template functions as shown below.

 tempalte<class F> void do_somthing(const std::map<int, int, F>& m) { } 

This is not necessarily bad, but my instincts tell me that having a type that ONLY can be viewed using common functions is bad. I think this works great for lambda functions, but more on that. 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 specific type to work with, my_map

hope this helps!

+2
source

Source: https://habr.com/ru/post/950993/


All Articles