I'm playing with functional programming in C++20 and write something like that:
template <class OuterFn, class InnerFn, class... Args>
concept Composable =
std::invocable<OuterFn, std::invoke_result_t<InnerFn, Args...>>;
template <class OuterFn, class InnerFn>
constexpr auto
compose(OuterFn&& outer, InnerFn&& inner)
{
return [
out = std::forward<OuterFn>(outer),
in = std::forward<InnerFn>(inner)
]<class... Args>(Args && ... args)
requires Composable<OuterFn, InnerFn, Args...>
{
using std::invoke, std::forward;
return invoke(out, invoke(in, forward<Args>(args)...));
};
}
template <class OuterFn, class InnerFn>
constexpr auto
operator*(OuterFn&& outer, InnerFn&& inner)
{
using std::forward;
return compose(forward<OuterFn>(outer), forward<InnerFn>(inner));
}
template <class... RestFn>
constexpr auto
compose(RestFn&&... rest)
{
return (std::forward<RestFn>(rest) * ...);
}
This is work, but I want to refactor compose for two arguments by using std::bind* instead of lambda. So, I think that this:
using eq_t = std::equal_to<const std::string_view>;
constexpr auto eq_42 = std::bind_front(eq_t{}, "42");
is clearly than(especially if using function without overloaded operator for it):
constexpr auto eq_42 = [](const std::string_view sv){ return sv == "42"; };
Maybe You have an ideas how can I do this, or reasons why I can't do this?
The problem is how to retrieve arguments to inner function.
std::bind(outer, std::bind_front(inner));
I tried this for variadic template arguments(and million other variants) by analogy from
std::bind(outer, std::bind(inner, _1)); for one argument, but it doesn't work.
P.S. Sorry for my english)
std::bind, which is outdated and not recommended?std::bindis not "simple, readable, laconic" compared to a lambdastd::bind(). For example, in this CppCon video, at 25:08 .. 33:05 (already from 2015) about<functional>, Stephan T. Lavavej (the implementor of Visual Studio's C++ Standard Library) wraps it up by saying, "Avoid usingbind()!" And as I understand,std::bind()is essentially an obsolete construct that was invented only because there were no lambdas yet in the C++ language.