C++: Using boost lambda to get maximum values in a std::tr1::unordered_map
I have a std::tr1::unordered_map<int, A> map;
where A is a class with a member variable (int x).
I would like to find the key i in map such that map[i].x is maximum.
I know that I can write a functor to go with std::max_eleme开发者_开发技巧nt. How do I do this instead, using boost lambda (I am trying to learn it) ? I do not have C++0x.
As an added question, what if I had class A defined as below:
class A { int x; int y; };
And I wanted to find the maximum w.r.t x (if that maximum was 0, find the maximum wrt to y). Again, one solution would be to iterate over the tuples of the map (keeping both maxima in memory). Is there a way to modify max_element to do this ?
boost.lambda uses boost.bind to access member variables. It comes up a bit wordy:
typedef std::tr1::unordered_map<int, A> map_t;
map_t m;
A max_a = std::max_element(m.begin(), m.end(),
bind(&A::x, bind(&map_t::value_type::second, _1))
< bind(&A::x, bind(&map_t::value_type::second, _2))
)->second;
test: https://ideone.com/V6SZL
You may save half the headache with boost.range
A max_a = *boost::max_element(m | map_values, bind(&A::x, _1) < bind(&A::x, _2));
But in practice, I think, a functor would be best.
Since you're just starting to learn Boost.Lambda, now is the perfect time to forget it exists and learn Boost.Phoenix instead. Boost.Phoenix is the replacement for Boost.Lambda and is considerably more powerful, and often more succinct:
typedef std::tr1::unordered_map<int, A> map_t;
map_t m;
int i = std::max_element(
m.begin(),
m.end(),
bind(&A::x, at_c<1>(_1)) < bind(&A::x, at_c<1>(_2))
)->first;
A& max_a = m[i];
Note that Boost.Phoenix v2 is currently a sublibrary of Boost.Spirit, but in 1.47.0 Boost.Phoenix v3 is slated to be released as a proper standalone Boost library.
精彩评论