#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;
Вы можете сэкономить половину головной боли с 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-библиотеку.