Ap31
Ap31

Reputation: 3314

Using `std::min` as an algorithm parameter

So I ran into this problem: I need to replace every element of the std::vector<int> with the minimum of whatever came before it (inclusive).

Naturally std::partial_sum comes to mind - if I could pass std::min as the BinaryOp, it would do the job.

Well turns out I can't do that because std::min<int> is an overloaded function - it works for both int and initializer_list<int> and partial_sum template can't be instantiated with the unknown type.

Usually this is resolved by having a class with a templated operator(), like std::plus<void> etc, but standard library doesn't seem to have one for min and max.

I feel like I either have to implement my own T min<T>(T,T), which will be an exact clone of std::min with the exception of not having an initializer_list overload, or to implement my own class min akin to std::plus. Both feel kinda wrong because one would expect standard library to have such a basic thing, and also basic things are often tricky to implement:)

So here are my questions:

  1. Is there any proper way to solve the problem in question? i.e. without introducing new vague constructs/writing more than a couple of lines of code.
  2. Is it correct to assume that this became a problem in C++11, after initializer_list overload of min was introduced? So C++11 broke the code that relied on explicitly instantiated std::min?

Thank you!

Upvotes: 27

Views: 3482

Answers (3)

Igor
Igor

Reputation: 33

If the above doesn't compile, try to add const modifier:

const int& (*min)(const int&, const int&) = std::min<int>;

Upvotes: 1

Caleth
Caleth

Reputation: 62686

You can initialise a pointer-to-function variable of appropriate type and pass that, or explicitly static_cast.

int& (*min)(int&, int&) = std::min<int>;
std::partial_sum(v.begin(), v.end(), v.begin(), min);

Upvotes: 22

yuri kilochek
yuri kilochek

Reputation: 13486

Wrap it in a lambda:

std::partial_sum(v.begin(), v.end(), v.begin(), [](auto& a, auto& b) {
    return std::min(a, b);
});

Upvotes: 33

Related Questions