C : Использование boost lambda для получения максимальных значений в std::tr1::unordered_map

#c #algorithm #boost #lambda

#c #алгоритм #повысить #лямбда

Вопрос:

У меня есть a std::tr1::unordered_map<int, A> map; где A — класс с переменной-членом (int x).

Я хотел бы найти ключ i в map таким образом, чтобы map[i].x был максимальным.

Я знаю, что могу написать функтор для std::max_element. Как мне сделать это вместо этого, используя boost lambda (я пытаюсь его изучить)? У меня нет C 0x.

В качестве дополнительного вопроса, что, если бы у меня был класс A, определенный следующим образом:

класс A { int x; int y; };

И я хотел найти максимальное значение w.r.t x (если это максимальное значение равно 0, найдите максимальное значение, равное y). Опять же, одним из решений было бы перебирать кортежи карты (сохраняя оба максимума в памяти). Есть ли способ изменить max_element для этого?

Ответ №1:

boost.lambda использует boost.bind для доступа к переменным-членам. Это немного многословно:

 typedef std::tr1::unordered_map<int, A> map_t;
map_t m;

A max_a = std::max_element(m.begin(), m.end(),
                bind(amp;A::x, bind(amp;map_t::value_type::second, _1))
              < bind(amp;A::x, bind(amp;map_t::value_type::second, _2))
         )->second;
  

тест:https://ideone.com/V6SZL

Вы можете сэкономить половину головной боли с boost.range

 A max_a = *boost::max_element(m | map_values, bind(amp;A::x, _1) < bind(amp;A::x, _2));
  

Но на практике, я думаю, функтор был бы лучшим.

Ответ №2:

Поскольку вы только начинаете изучать Boost.Лямбда, сейчас самое подходящее время забыть о ее существовании и изучить Boost.Вместо этого Phoenix. Повышение.Phoenix является заменой Boost.Lambda и значительно более мощный и часто более краткий:

 typedef std::tr1::unordered_map<int, A> map_t;
map_t m;

int i = std::max_element(
    m.begin(),
    m.end(),
    bind(amp;A::x, at_c<1>(_1)) < bind(amp;A::x, at_c<1>(_2))
)->first;
Aamp; max_a = m[i];
  

Обратите внимание, что Boost.Phoenix v2 в настоящее время является дочерней библиотекой Boost.Spirit, но в версии 1.47.0 Boost.Phoenix v3 планируется выпустить как надлежащую автономную Boost-библиотеку.