Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use std::accumulate with std::min?

I am trying to combine std::accumulate with std::min. Something like this (won't compile):

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

Is it possible? Is it possible to do without writing wrapper functor for std::min?
I know that I can do this with lambdas:

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

And I know there is std::min_element. I am not trying to find min element, I need to combine std::accumulate with std::min (or ::min) for my library which allows function-programming like expressions in C++.

like image 699
Leonid Volnitsky Avatar asked Jul 24 '12 07:07

Leonid Volnitsky


People also ask

Is std :: accumulate faster?

As I expect, the manually unrolled loop is the fastest one, but more interesting is that std::accumulate is much slower than simple loop.

What does std :: accumulate do?

std::accumulate() is a built-in function in C++'s Standard Template Library. The function takes in a beginning iterator, an ending iterator, initial value, and (by default) computes the sum of the given initial value and the elements in the given range. The function can also​ be used for left folding.

Should I use std :: list?

From a performance standpoint, the best reason to use std::list is so that when later on your app is suffering badly for performance and needs "an optimziation pass", you can replace it with another data structure and look like a hero.


1 Answers

The problem is that there are several overloads of the min function:

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);

Therefore, your code is ambiguous, the compiler does not know which overload to choose. You can state which one you want by using an intermediate function pointer:

#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);
}
like image 147
Luc Touraille Avatar answered Oct 13 '22 22:10

Luc Touraille