Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert function with std::array of doubles as argument or the doubles separately as arguments

I want to make a method convert that takes a general function bar (can be an std::function, lambda, functor,...) and converts it to an std::function<double(std::array<double, 3>)>. The function bar can either be:

  • a function taking std::array<double, 3> as an argument and returning a double. In this case, convert is not difficult to write:

code:

template<typename F>
std::function<double(std::array<double, 3>)> convert (F& bar)
{
    std::function<double(std::array<double,3>)> bar_converted = bar;
    return bar_converted;
}
  • a function taking three separate doubles as an argument and returning a double. Also in this case, convert is not too difficult to write:

code:

template<typename F>
std::function<double(std::array<double, 3>)> convert(F& bar)
{
    std::function<double(std::array<double,3>)> bar_converted;
    auto array_bar = [bar]( std::array<double, 3> x)->double{ return bar(x[0], x[1], x[2]); };
    bar_converted = array_bar;
    return bar_converted;
}

The problem is that I do not have a clue how to combine these two convert methods, or whether this is even possible?

like image 962
JorenV Avatar asked Dec 07 '25 04:12

JorenV


1 Answers

I'll start with how I would write this in C++17:

template<typename F>
std::function<double(std::array<double, 3>)> convert(F&& f) // <== NB: forwarding ref
{
    if constexpr (std::is_invocable_v<F&, std::array<double, 3>) {
        // direct case
        return std::forward<F>(f);
    } else {
        // unpacking case
        return [f=std::forward<F>(f)](std::array<double, 3> arr) {
            return std::apply(f, arr);
        };
    }
}

In C++14, you don't have if constexpr, is_invocable, or apply. The first can be achieved by just doing tag dispatch (you invoke a helper function with either std::true_type or std::false_type) and the other two can be implemented in C++14 just fine, and are really useful helper functions that you will likely need for lots of other things anyway.

like image 168
Barry Avatar answered Dec 08 '25 17:12

Barry