Create a function, compose, whose two arguments f and g, are both functions with one argument. The result of compose is to be a function of one argument, (lets call the argument x), which works like applying function f to the result of applying function g to x, i.e,
- compose(f, g) (x) = f(g(x))
Reference: Function composition
Hint: In some languages, implementing compose correctly requires creating a closure.
#include <functional> #include <cmath> #include <iostream> // functor class to be returned by compose function template <class Fun1, class Fun2> class compose_functor : public std::unary_function<typename Fun2::argument_type, typename Fun1::result_type> { protected: Fun1 f; Fun2 g; public: compose_functor(const Fun1& _f, const Fun2& _g) : f(_f), g(_g) { } typename Fun1::result_type operator()(const typename Fun2::argument_type& x) const { return f(g(x)); } }; // we wrap it in a function so the compiler infers the template arguments // whereas if we used the class directly we would have to specify them explicitly template <class Fun1, class Fun2> inline compose_functor<Fun1, Fun2> compose(const Fun1& f, const Fun2& g) { return compose_functor<Fun1,Fun2>(f, g); } int main() { std::cout << compose(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl; return 0; }
composing std::function
#include <iostream> #include <functional> #include <cmath> template <typename A, typename B, typename C> std::function<C(A)> compose(std::function<C(B)> f, std::function<B(A)> g) { return [f,g](A x) { return f(g(x)); }; } int main() { std::function<double(double)> f = sin; std::function<double(double)> g = asin; std::cout << compose(f, g)(0.5) << std::endl; return 0; }
This much simpler version uses decltype(auto)
.
#include <iostream> #include <math.h> template <class F, class G> decltype(auto) compose(F&& f, G&& g) { return [=](auto x) { return f(g(x)); }; } int main() { std::cout << compose(sin, asin)(0.5) << "\n"; return 0; }
GCC’s C++ library has a built-in compose function
#include <iostream> #include <cmath> #include <ext/functional> int main() { std::cout << __gnu_cxx::compose1(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl; return 0; }
Content is available under GNU Free Documentation License 1.2.