#include // For declval. #include #include #include #include /* Partial application helper. */ template< class F, class Arg > struct PApply { F f; Arg arg; template< class F_, class Arg_ > PApply( F_&& f, Arg_&& arg ) : f(std::forward(f)), arg(std::forward(arg)) { } /* * The return type of F only gets deduced based on the number of arguments * supplied. PApply otherwise has no idea whether f takes 1 or 10 args. */ template< class ... Args > auto operator() ( Args&& ...args ) -> decltype( f(arg,std::declval()...) ) { return f( arg, std::forward(args)... ); } }; template< class F, class Arg > PApply papply( F&& f, Arg&& arg ) { return PApply( std::forward(f), std::forward(arg) ); } /* Apply f to cont. */ template< class F > std::array fs( F&& f, std::array cont ) { std::transform( std::begin(cont), std::end(cont), std::begin(cont), std::forward(f) ); return cont; } std::ostream& operator << ( std::ostream& out, const std::array& c ) { std::copy( std::begin(c), std::end(c), std::ostream_iterator(out, ", ") ); return out; } int f1( int x ) { return x * 2; } int f2( int x ) { return x * x; } int main() { std::array xs = {{ 0, 1, 2, 3 }}; std::array ys = {{ 2, 4, 6, 8 }}; auto fsf1 = papply( fs, f1 ); auto fsf2 = papply( fs, f2 ); std::cout << "xs:\n" << "\tfsf1: " << fsf1(xs) << '\n' << "\tfsf2: " << fsf2(xs) << "\n\n" << "ys:\n" << "\tfsf1: " << fsf1(ys) << '\n' << "\tfsf2: " << fsf2(ys) << '\n'; }