user231536
user231536

Reputation: 2711

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_element. 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 ?

Upvotes: 1

Views: 1159

Answers (2)

ildjarn
ildjarn

Reputation: 62975

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.

Upvotes: 1

Cubbi
Cubbi

Reputation: 47438

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.

Upvotes: 2

Related Questions