Aplicação parcial com um lambda C ++?
EDIT: Eu uso curry abaixo, mas foram informados que esta é uma aplicação parcial.
Eu tenho tentado descobrir como alguém poderia escrever uma função de curry em C ++, e eu realmente descobri isso!
#include <stdio.h>
#include <functional>
template< class Ret, class Arg1, class ...Args >
auto curry( Ret f(Arg1,Args...), Arg1 arg )
-> std::function< Ret(Args...) >
{
return [=]( Args ...args ) { return f( arg, args... ); };
}
E eu escrevi uma versão para lambdas também.
template< class Ret, class Arg1, class ...Args >
auto curry( const std::function<Ret(Arg1,Args...)>& f, Arg1 arg )
-> std::function< Ret(Args...) >
{
return [=]( Args ...args ) { return f( arg, args... ); };
}
Os testes:
int f( int x, int y )
{
return x + y;
}
int main()
{
auto f5 = curry( f, 5 );
auto g2 = curry( std::function<int(int,int)>([](int x, int y){ return x*y; }), 2 );
printf("%d\n",f5(3));
printf("%d\n",g2(3));
}
Que nojo! A linha que inicializa o g2 é tão grande que eu poderia ter sido curry manualmente.
auto g2 = [](int y){ return 2*y; };
Muito mais curto. Mas como a intenção é ter uma função de curry realmente genérica e conveniente, eu poderia (1) escrever uma função melhor ou (2) de alguma forma meu lambda construir implicitamente uma função std ::? Temo que a versão atual viole a regra da menor surpresa quando f não é uma função livre. Especialmente irritante é como nenhuma função de make_function ou similar que eu conheço parece existir. Realmente, minha solução ideal seria apenas uma chamada para std :: bind, mas não tenho certeza de como usá-lo com os modelos variadic.
PS: Sem impulso, por favor, mas eu vou resolver se nada mais.
EDIT: eu já sei sobre std :: bind. Eu não estaria escrevendo esta função se std :: bind fizesse exatamente o que eu queria com a melhor sintaxe. Este deve ser mais um caso especial em que apenas liga o primeiro elemento.
Como eu disse, minha solução ideal deveriausar ligar, mas se eu quisesse usar isso, eu usaria isso.