I'm trying to create a function 'compose' returning the composition of callable objects given as arguments.
In mathematics, It would be the following:
F = h(g(f(x)))
Here an implementation in C++:
template <typename F>
auto compose(F&& f)
{
return[f = std::forward<F>(f)](auto&&... args){
return f(std::forward<decltype(args)>(args)...);
};
}
template <typename F, typename G, typename... Functions>
auto compose(F&& f, G&& g, Functions&&... functions)
{
return compose(
[f = std::forward<F>(f), g = std::forward<G>(g)](auto&&... args)
{
return f(g(std::forward<decltype(args)>(args)...));
},
std::forward<Functions>(functions)...);
}
This works like a charm if I provide lambda functions as arguments:
auto f = compose(
[](auto value) { return std::sin(value); },
[](auto value) { return std::asin(value); }
);
However, if I use directly overloaded functions from the standard (without encapsulating them within a lambda), the compiler cannot deduce which overload to pick to instantiate the template:
auto g = compose(
std::sin,
std::asin
);
Here the errors using Microsoft C++ compiler:
error C2672: 'compose': no matching overloaded function found
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'F'
message : see declaration of 'compose'
error C2783: 'auto compose(F &&,G &&,Functions &&...)': could not deduce template argument for 'G'
message : see declaration of 'compose'
error C2780: 'auto compose(F &&)': expects 1 arguments - 2 provided
message : see declaration of 'compose'
Is there a way to state the function types (of std::sin and std::asin) we want to use while creating the composed function ?