Есть ли вариант min_element, который принимает функцию проекции?

std::min_element вернет наименьший элемент, как определено operator<(T,T) или с помощью пользовательского предиката bool Pred(T,T), Есть ли аналогичная функция, которая возвращает элемент, для которого функция проекции f(T)->R принимает минимальное значение?

Очевидно, я могу определить bool Pred(t1,t2) { return f(t1) < f(t2); } но это немного неудобно, когда f лямбда.

8

Решение

Почему бы просто не определить генератор предикатов less_by который, принимая лямбду, возвращает функтор, который выполняет эту работу за вас?

template <typename Proj>
struct less_by_t {
Proj p;

template <typename T>
bool operator ()(T const& a, T const& b) const {
return p(a) < p(b);
}
};

template <typename Proj>
less_by_t<Proj> less_by(Proj p) {
return {p};
}
auto result = std::min_element(begin, end, less_by([](T const& x){return …;}));
4

Другие решения

Почему бы не использовать boost::transform_iterator (который раньше назывался projection_iterator_adaptor) от Библиотека Boost.Iterator

auto Pred = [](some_value_type const& x){ /* your lambda here */ };
auto result = std::min_element(
boost::make_transform_iterator(begin(container), Pred),
boost::make_transform_iterator(end(container), Pred)
).base();
//^^^^^^^  <-- to get back an iterator to the original sequence

Преимущество этого по сравнению с написанием специального менее предиката состоит в том, что вы можете повторно использовать этот подход для всех других алгоритмов (например, для std::max_element вам нужен особый предикат и т. д.).

5

По вопросам рекламы [email protected]