Search code examples
c++templatesfunctional-programmingstd-function

How to use std::max or std::min as function parameter


I like to pass std::max or std::min into a function. One can write code like this

Definition of the function

void foo (std::function<double(double, double)> extreme) {
    ...
    const double e = extreme(rhs, lhs);
    ...
}

On can call the function using a lambda

foo([](const double rhs, const double lhs) { return std::max(rhs, lhs); });

This is quite ugly. I would prefer to write code like this

foo(std::max);

This does not compile. Is this or something more readable possible?


Solution

  • The following works:

    void foo (std::function<double const&(double const&, double const&)>) {}
    void foo2 (double const&(double const&, double const&)){}
    
    int main () {
        foo((double const&(*)(double const&, double const&))(std::max<double>));
        foo2(std::max<double>);
    }
    

    Note that we always need to use std::max<double>.

    In the call to foo, as it takes a std::function, theres no good way the compiler can work out which overloaded version of std::max to use and so you need to cast it to the correct type.

    For the second one, as foo2 takes the raw function, it just works.

    Note that I've explicitly use double const&, as the plain T versions (as in not having the const&) of std::max take an initialiser list and so there's no way to cast it to what you need.

    So to get it working with the foo as written, you'll have to use a lambda or overload or wrapper of some sort.

    So the simplest way would be to use the knowledge above of what does work, and add an overload:

    void foo(double const&(*func)(double const&, double const&) )
    {
        foo([&func](double a, double b){return func(a, b);});
    }
    

    and then foo(std::max<double>); will work