Функция, возвращающая лямбда-выражение
Интересно, можно ли написать функцию, которая возвращает лямбда-функцию в С++ 11. Конечно, одна проблема заключается в том, как объявить такую функцию. Каждая лямбда имеет тип, но этот тип не выражен в С++. Я не думаю, что это сработает:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
И это:
int(int) retFun();
Я не знаю никаких автоматических преобразований из лямбда, например, указателей на функции или некоторых таких. Это единственное решение, которое обрабатывает объект функции и возвращает его?
Ответы
Ответ 1
Вам не нужен объект функции, созданный вручную, просто используйте std::function
, в которую можно преобразовать лямбда-функции:
Этот пример возвращает целочисленную идентификационную функцию:
std::function<int (int)> retFun() {
return [](int x) { return x; };
}
Ответ 2
Для этого простого примера вам не нужно std::function
.
Из стандарта § 5..1.2/6:
Тип замыкания для лямбда-выражения без лямбда-захвата имеет публичную не виртуальную неявную функцию преобразования const, чтобы указатель на функцию, имеющую тот же параметр и возвращаемые типы, что и оператор вызова функции замыкания. Значение, возвращаемое этой функцией преобразования, должно быть адресом функции, которая при вызове имеет тот же эффект, что и при вызове оператора вызова функции закрытия.
Поскольку ваша функция не имеет захвата, это означает, что лямбда может быть преобразована в указатель на функцию типа int (*)(int)
:
typedef int (*identity_t)(int); // works with gcc
identity_t retFun() {
return [](int x) { return x; };
}
Что я понимаю, исправьте меня, если я ошибаюсь.
Ответ 3
Вы можете вернуть лямбда-функцию из другой лямбда-функции, так как вы не должны явно указывать тип возврата лямбда-функции. Просто напишите что-нибудь подобное в глобальной области:
auto retFun = []() {
return [](int x) {return x;};
};
Ответ 4
Хотя вопрос конкретно задает вопрос о С++ 11, для других, которые спотыкаются об этом и имеют доступ к компилятору С++ 14, С++ 14 теперь позволяет выводить типы возвращаемых данных для обычных функций. Таким образом, пример в вопросе может быть скорректирован просто для работы по желанию, просто отбросив предложение -> decltype
... после списка параметров функции:
auto retFun()
{
return [](int x) { return x; }
}
Обратите внимание, однако, что это не будет работать, если в функции появится более одного return <lambda>;
. Это связано с тем, что ограничение на вывод типа возврата заключается в том, что все операторы return должны возвращать выражения одного и того же типа, но каждый лямбда-объект получает свой собственный уникальный тип компилятором, поэтому выражения return <lambda>;
будут иметь разные типы.
Ответ 5
Вы должны написать так:
auto returnFunction = [](int x){
return [&x](){
return x;
}();
};
чтобы получить ваш возврат как функцию, и использовать его следующим образом:
int val = returnFunction(someNumber);