问题
Is there a reason why I cannot pass a comparison functor to a map as a constructor argument:
map<int, string, greater<int>> foo;
//map<int, string> foo(greater<int>()); Doesn't work
Or why I cannot pass a lambda without providing my own comparison type:
map<int, string, function<bool(const int&, const int&)>> bar([](const int& lhs, const int& rhs){ return lhs > rhs; });
//map<int, string> bar([](const int& lhs, const int& rhs){ return lhs > rhs; }); Doesn't work
I'd like to just be able to declare map<int, string> and construct it with a comparator. Why can't I?
[Live Example]
回答1:
This question stems from a misconception. To clear that up:
Functors are objects not functions
Trying to assign a function pointer or a lambda to an object doesn't make any sense. So this cannot be done: The way to define a map<int, string> bar([](const int& lhs, const int& rhs){ return lhs > rhs; });map which takes a function pointer or lambda is to use the template arguments from the question: map<int, string, function<bool(const int&, const int&)>>
Halfway between the two ill-conceived options in the question is another misconception: Doesn't work because the comparator template argument is the type of a member of map<int, string, [](const int& lhs, const int& rhs){ return lhs > rhs; }>map, not the intialization value. So a map using a function pointer or lambda comparator must always have that value passed to the map constructor: map<int, string, function<bool(const int&, const int&)>> bar([](const int& lhs, const int& rhs){ return lhs > rhs; }) Otherwise function<bool(const int&, const int&)>() would be used for comparisons in the map.
This is probably already clear by now, but since functors are objects you cannot pass an unrelated object is the construction value of a completely different type of object. Calling is like calling map<int, string> foo(greater<int>()). The only acceptable compatator constructor argument to a less<int> foo = greater<int>map whose comparator template argument is a functor is something that can be converted into an object of the functor type in the template argument: map<int, string, greater<int>> foo(greater<int>{}) This is obviously unnecessary, because if no argument was provided and the greater<int> was default constructed the same member initialization of the map would result, so map<int, string, greater<int>> is sufficent.
来源:https://stackoverflow.com/questions/35757307/map-comparison-constructor-parameter