Каковы конструктивные соображения из-за отсутствия std :: Maximum?

Стандартная библиотека C ++ поддерживает различные функциональные объекты, в том числе ассоциативные бинарные функторы std::plus а также std::multiplies, которые являются полезными аргументами для различных общих складка алгоритмы, такие как std::accumulate, std::reduce, или же tbb::parallel_reduce.

Я осуществлял Дерево Фенвика принять ассоциативный бинарный оператор в качестве аргумента шаблона (по умолчанию std::plus<void>). Одним из возможных вариантов аргумента является оператор максимума (и минимума)

template<typename T=void>
struct maximum
{
constexpr T operator() (T const&x, T const&y) const
{ return x>y? x:y; }
};

template<>
struct maximum<void>
{
template<typename T>
constexpr T operator() (T const&x, T const&y) const
{ return x>y? x:y; }
};

когда дерево Фенвика может найти максимальное значение в префиксе любого элемента или в диапазоне элементов в логарифмическом времени.

Однако, к моему удивлению, такой бинарный максимальный функтор не существует в стандартной библиотеке. Я могу, конечно, использовать свой собственный, но это делает невозможным специализировать код для общего пользования. Например, обновление дерева Фенвика для замены одного элемента может быть оптимизировано в случае максимума: проход дерева может быть прекращен, если предыдущий максимум в диапазоне, представленном узлом дерева, превышает новое значение.

Итак, есть ли серьезные причины не иметь std::maximum а также std::minimum (Кроме как никто еще не предложил это)?

Обратите внимание, что std::max нет варианта Вот:

std::accumulate(v.begin(), v.end(), 0, std::max<T>);

не работает (в C ++ 11, но это было раньше), в отличие от (с использованием выше maximum)

std::accumulate(v.begin(), v.end(), 0, std::plus<void>{});
std::accumulate(v.begin(), v.end(), 0, maximum<void>{});

Другим вариантом был бы общий Выбрать Функтор, например, принимает в качестве аргумента функтор сравнения.

template<typename T, typename Compare = std::greater<T> >
struct select
{
constexpr T operator()(T const&x, T const&y) const
{ return comp(x,y)? x:y; }
private:
Compare comp;
};

а также select<void> аналогичным образом.

-6

Решение

Accumulate — это шаблонная функция, которая просто пытается вызвать функцию-аккумулятор, будь то Callable или обычная функция (ну, сама обычная функция называется Callable), поэтому использование этого полностью допустимо

cout << std::accumulate(v.begin(), v.end(), 0, std::max<YOUR_TYPE_HERE>);

Если ваш тип был сложным (как и все, что не применимо к max), вы можете передать пользовательское лямбда-выражение (только C ++ после 11):

cout << std::accumulate(v.begin(), v.end(), 0, [](int a, int b){return a > b ? a : b;});

(заменить int с вашим типом, и заменить return a > b ? a : b; с твоей разыскиваемой логикой)

Если ваш компилятор отказался компилировать первый и вы используете что-то до C ++ 11, вы можете попробовать эту строку (небезопасно)

cout << std::accumulate(v.begin(), v.end(), 0, std::ptr_fun(std::max<int>));

std::ptr_fun преобразует ЛЮБУЮ ФУНКЦИЮ в функциональный объект, чтобы его можно было использовать, см. эту ссылку http://www.cplusplus.com/reference/functional/ptr_fun/

Также есть класс под названием std::pointer_to_binary_function это может помочь вам больше. Вот его ссылка http://www.cplusplus.com/reference/functional/pointer_to_binary_function/

-1

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

Других решений пока нет …

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