#include <algorithm>
#include <functional>
#include <iterator>
#include <vector>
template <typename ContainerOut, typename ContainerIn, typename F>
ContainerOut Map( const F& f, const ContainerIn& xs )
{
ContainerOut ys;
// For performance reasons one would use
// ys.reserve( xs.size() )
// and std::back_inserter instead of std::inserter
// if ys is a std::vector.
auto it = std::inserter( ys, end( ys ) );
std::transform( begin( xs ), end( xs ), it, f );
return ys;
}
template <typename Ret, typename Arg1, typename ...Args>
auto Curry( Ret f(Arg1, Args...), Arg1 arg ) -> std::function<Ret(Args...)>
{
return [=]( Args ...args ) { return f( arg, args... ); };
}
int main()
{
auto square = [](int x){ return x*x; };
typedef std::vector<int> Row;
typedef std::vector<Row> Mat;
Mat mat;
auto squareElements = Curry(Map<Row>, square);
Mat squaredMat = Map<Mat>(squareElements, mat);
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpdGVyYXRvcj4KI2luY2x1ZGUgPHZlY3Rvcj4KCnRlbXBsYXRlIDx0eXBlbmFtZSBDb250YWluZXJPdXQsIHR5cGVuYW1lIENvbnRhaW5lckluLCB0eXBlbmFtZSBGPgpDb250YWluZXJPdXQgTWFwKCBjb25zdCBGJiBmLCBjb25zdCBDb250YWluZXJJbiYgeHMgKQp7CiAgICBDb250YWluZXJPdXQgeXM7CiAgICAvLyBGb3IgcGVyZm9ybWFuY2UgcmVhc29ucyBvbmUgd291bGQgdXNlCiAgICAvLyB5cy5yZXNlcnZlKCB4cy5zaXplKCkgKQogICAgLy8gYW5kIHN0ZDo6YmFja19pbnNlcnRlciBpbnN0ZWFkIG9mIHN0ZDo6aW5zZXJ0ZXIKICAgIC8vIGlmIHlzIGlzIGEgc3RkOjp2ZWN0b3IuCiAgICBhdXRvIGl0ID0gc3RkOjppbnNlcnRlciggeXMsIGVuZCggeXMgKSApOwogICAgc3RkOjp0cmFuc2Zvcm0oIGJlZ2luKCB4cyApLCBlbmQoIHhzICksIGl0LCBmICk7CiAgICByZXR1cm4geXM7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBSZXQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIC4uLkFyZ3M+CmF1dG8gQ3VycnkoIFJldCBmKEFyZzEsIEFyZ3MuLi4pLCBBcmcxIGFyZyApIC0+IHN0ZDo6ZnVuY3Rpb248UmV0KEFyZ3MuLi4pPgp7CiAgICByZXR1cm4gWz1dKCBBcmdzIC4uLmFyZ3MgKSB7IHJldHVybiBmKCBhcmcsIGFyZ3MuLi4gKTsgfTsKfQoKaW50IG1haW4oKQp7CiAgICBhdXRvIHNxdWFyZSA9IFtdKGludCB4KXsgcmV0dXJuIHgqeDsgfTsKCiAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPGludD4gUm93OwogICAgdHlwZWRlZiBzdGQ6OnZlY3RvcjxSb3c+IE1hdDsKICAgIE1hdCBtYXQ7CiAgICBhdXRvIHNxdWFyZUVsZW1lbnRzID0gQ3VycnkoTWFwPFJvdz4sIHNxdWFyZSk7CiAgICBNYXQgc3F1YXJlZE1hdCA9IE1hcDxNYXQ+KHNxdWFyZUVsZW1lbnRzLCBtYXQpOwp9
prog.cpp: In function 'int main()':
prog.cpp:32:49: error: no matching function for call to 'Curry(<unresolved overloaded function type>, main()::<lambda(int)>&)'
auto squareElements = Curry(Map<Row>, square);
^
prog.cpp:20:6: note: candidate: template<class Ret, class Arg1, class ... Args> std::function<Ret(Args ...)> Curry(Ret (*)(Arg1, Args ...), Arg1)
auto Curry( Ret f(Arg1, Args...), Arg1 arg ) -> std::function<Ret(Args...)>
^
prog.cpp:20:6: note: template argument deduction/substitution failed:
prog.cpp:32:49: note: couldn't deduce template parameter 'Ret'
auto squareElements = Curry(Map<Row>, square);
^