Можно ли использовать std:: накопить с std::min?

Я пытаюсь совместить std::accumulate с std::min, Примерно так (не скомпилируется):

vector<int> V{2,1,3};   
cout << accumulate(V.begin()+1, V.end(), V.front(), std::min<int>);

Является ли это возможным? Можно ли обойтись без написания функтора-обёртки для std::min?
Я знаю, что я могу сделать это с лямбдами:

vector<int> V{2,1,3};   
cout << std::accumulate(
    V.begin()+1, V.end(),
    V.front(), 
    [](int a,int b){ return min(a,b);}
);

И я знаю, что есть std::min_element, Я не пытаюсь найти минимальный элемент, мне нужно объединить std::accumulate с std::min (или же ::min) для моей библиотеки, которая позволяет программировать функции как выражения в C++.

3 ответа

Решение

Проблема в том, что есть несколько перегрузок min функция:

template <class T> const T& min(const T& a, const T& b);

template <class T, class BinaryPredicate>
const T& min(const T& a, const T& b, BinaryPredicate comp);

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

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
  std::vector<int> V{2,1,3};
  int const & (*min) (int const &, int const &) = std::min<int>;
  std::cout << std::accumulate(V.begin() + 1, V.end(), V.front(), min);
}

Очень старый вопрос, но может помочь кому-то еще:) Найти минимальную накопительную сумму.

C++ 14:

/*
Find the minimum accumulate sum.

input
4
4 -66 0 -11

output
-73

Explanation:
First sum == 4, minimum = 4
then, sum ==
  4 + -66 = -62, minimum == -62
  -62 + 0 = -62, minimum == -62
  -62 + -11 = -73, minimum == -73
*/
#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;

const int INF = 1e9;


int main(){
  int n;
  cin >> n;

  vi v;
  for (int i = 0 ; i < n ; ++i){
    int x;
    cin >> x;
    v.push_back(x);
  }

  int min_sum = v.front();
  accumulate(v.begin() + 1, v.end(), min_sum,
              [&min_sum](auto &x1, auto &x2){
                min_sum = min(min_sum, x1 + x2);
                return x1 + x2;
              });
  cout << "Minimum is: " << min_sum << '\n';

  return 0;
}

Из C++20 вы можете использовать std:: ranges ::min

      #include <algorithm>
#include <iostream>
#include <vector>
#include <numeric>
#include <climits>

int main() {
    std::vector<int> v{1,2,3,47,5};
    std::cout << std::accumulate(v.begin(), v.end(), INT_MAX, std::ranges::min) << std::endl; 
    std::cout << std::accumulate(v.begin(), v.end(), INT_MIN, std::ranges::max) << std::endl; 
}

1
47

Обратите внимание, что нет std::ranges::accumulate, как это не было сделано для C++20.

Другие вопросы по тегам