I was inspired from the C++ Ranges style for creating overloads of operator() inside the class and I found it very useful in many cases:
- Can be passed as an argument directly like lambda but unlike overloaded functions.
- Protected from ADL.
- Preventing from specifying template arguments (closely, but
.template operator()<...>)
For easy cases, I can handle it manually:
For overloaded function:
template <typename F, typename G>
constexpr auto compose(F&& f, G&& g) {
return [
f = std::forward<F>(f),
g = std::forward<G>(g)
]<typename... Ts>(Ts&&... args) {
if constexpr (std::is_void_v<std::invoke_result_t<G, Ts...>>) {
std::invoke_r<void>(g, std::forward<Ts>(args)...);
return std::invoke(f);
} else {
return std::invoke(f, std::invoke(g, std::forward<Ts>(args)...));
}
};
}
template <typename F, typename... Fs>
constexpr auto compose(F&& f, Fs&&... fs) {
return compose(std::forward<F>(f), compose(std::forward<Fs>(fs)...));
}
For Function Object:
namespace functors {
struct compose_fn {
template <typename... Fs>
constexpr auto operator()(Fs&&... fs) const noexcept {
return ::compose(std::forward<Fs>(fs)...);
}
};
inline constexpr compose_fn compose {};
}
Where I could use to pass it inside std::apply:
template <std::size_t N, typename F>
constexpr auto func_power(F f) {
auto return_identity_ = [&f]<std::size_t I>(std::integral_constant<std::size_t, I>) noexcept {
return f;
};
auto tup_ = [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return std::make_tuple(return_identity_(std::integral_constant<std::size_t, Is>{})...);
}(std::make_index_sequence<N>{});
/// apply:
return std::apply(functors::compose, tup_);
}
Whereas the global compose can't be passed because it's ambiguous.
The only thing I could get as general is this one:
[]<typename... Ts>(Ts&&... args){
return some_overloaded_function(std::forward<Ts>(args)...);
}
However, the following constraints will depend on the some_overloaded_function.
Is there a general way to wrap any overloaded functions into function objects by just implementing 1 tool (function, function object, etc.)?