Частичное применение с C ++ лямбда?
РЕДАКТИРОВАТЬ: я использую карри ниже, но мне сообщили, что это вместо частичного применения.
Я пытался выяснить, как можно написать функцию карри на C ++, и я действительно понял это!
#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... ); };
}
И я написал версию для лямбды тоже.
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... ); };
}
Тесты:
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));
}
Тьфу! Строка, инициализирующая g2, настолько велика, что я с таким же успехом мог бы сделать это вручную.
auto g2 = [](int y){ return 2*y; };
Гораздо короче. Но так как намерение состоит в том, чтобы иметь действительно универсальную и удобную функцию карри, могу ли я (1) написать лучшую функцию или (2) каким-то образом мою лямбду для неявного создания std :: function? Боюсь, что текущая версия нарушает правило наименьшего удивления, когда f не является свободной функцией. Особенно раздражает то, что кажется, что нет никакой make_function или подобного типа функции, о которой я знаю. На самом деле, моим идеальным решением будет просто вызов std :: bind, но я не уверен, как использовать его с шаблонами с переменным числом аргументов.
PS: пожалуйста, нет, но я согласен, если ничего больше.
РЕДАКТИРОВАТЬ: я уже знаю о std :: bind. Я бы не писал эту функцию, если бы std :: bind делал именно то, что я хотел, с лучшим синтаксисом. Это должно быть более частным случаем, когда он связывает только первый элемент.
Как я уже сказал, мое идеальное решение должноuse привязать, но если бы я хотел использовать это, я бы использовал это.