c ++ лямбда: возможно ли создать новую лямбду, закрыв открытые аргументы? - PullRequest
0 голосов
/ 28 января 2020

С агентами EIFFEL (https://www.eiffel.org/doc/solutions/Event_Programming_with_Agents#Open_and_Closed_Arguments) каждый имеет открытый и закрытый аргументы. Для меня это похоже на аргументы и захваты в лямбдах.

Интересно, могу ли я «закрыть / захватить» открытый аргумент лабды, чтобы получить новую лямбду с другой сигнатурой с меньшим количеством аргументов.

Примерно так:

std::function<void(int, float, string) baseLambda = [](int d, float f, string s){printf("%d%f%s",d,f,s.c_str())};
std::function<void(int,string)> partiallyClosedLambda = baseLambda(?, 1.0f, ?);
partiallyClosedLambda(3,"foo"); // would print "31.0foo"

Есть ли такой механизм в c ++?

конечно, я мог бы определить новую лямбду вручную

std::function<void(int,string)> partiallyClosedLambda = [&baseLambda](int d, string s) { baseLambda(d, 1.0f, s); }

Но мне интересно, есть ли какой-нибудь синтаксис c сахара для этого?

Ответы [ 2 ]

1 голос
/ 28 января 2020

Существует std :: bind , который может быть тем, что вы ищете:

using namespace std::placeholders;  // for _1, _2, etc.
auto base = [](int d, float f, std::string s) { /* do stuff */ };
auto partially_closed = std::bind(base, _1, 1.0f, _2);

// now you can do
partially_closed(10, "hello!");

Живой пример: http://coliru.stacked-crooked.com/a/410c788caec826c9

Обратите внимание, что хранение лямбд в std::function, как правило, не идеально, если вам не нужно (например, в классе), поскольку std::function иногда потребуется выполнять дополнительные выделения (так как это обертка типа polymorphi c) , Использование auto создает переменную с точным (неименованным) лямбда-типом, которая, очевидно, не требует дополнительных выделений.

0 голосов
/ 28 января 2020

Просто объявите новую лямбду, которая захватывает первую. Затем вы можете назвать первую лямбду в теле второй лямбды.

auto baseLambda = [](int d, float f, string s) { printf("%d%f%s", d, f, s.c_str()); };

auto partiallyClosedLambda = [&baseLambda](int d, string s) { 
    // Call the first lambda. We pass the `d` and `s` parameters we receive as arguments from the second (current) lambda, while the float argument is hard-coded as 1.0
    baseLambda(d, 1.0, s); 
};
partiallyClosedLambda(3, "foo"); // would print "31.0foo"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...