Функция, возвращающая лямбда-выражение - PullRequest
81 голосов
/ 18 января 2011

Интересно, возможно ли написать функцию, которая возвращает лямбда-функцию в C ++ 11. Конечно, одна проблема заключается в том, как объявить такую ​​функцию. У каждой лямбды есть тип, но этот тип не выражается в C ++. Я не думаю, что это сработает:

auto retFun() -> decltype ([](int x) -> int)
{
    return [](int x) { return x; }
}

Ни это:

int(int) retFun();

Мне не известны какие-либо автоматические преобразования из лямбд, например, в указатели на функции или что-то подобное Является ли единственное решение, вручную создающее функциональный объект и возвращающее его?

Ответы [ 4 ]

92 голосов
/ 18 января 2011

Вам не нужен объект функции, созданный вручную, просто используйте std::function, к которому можно преобразовать лямбда-функции:

Этот пример возвращает целочисленную идентификационную функцию:

std::function<int (int)> retFun() {
    return [](int x) { return x; };
}
28 голосов
/ 19 января 2011

Для этого простого примера вам не нужно std::function.

Из стандарта §5.1.2 / 6:

Тип закрытия для лямбда-expression без лямбда-захвата имеет открытую не виртуальную неявную функцию преобразования констант в указатель на функцию, имеющую тот же параметр и возвращаемые типы, что и оператор вызова функции типа замыкания.Значение, возвращаемое этой функцией преобразования, должно быть адресом функции, которая при вызове имеет тот же эффект, что и вызов оператора вызова функции типа замыкания.

Поскольку ваша функция не имеет перехвата, это означает, что лямбда может быть преобразована в указатель на функцию типа int (*)(int):

typedef int (*identity_t)(int); // works with gcc
identity_t retFun() { 
  return [](int x) { return x; };
}

Это мое понимание, поправьте меня, если я ошибаюсь.

19 голосов
/ 05 ноября 2011

Вы можете вернуть лямбда-функцию из другой лямбда-функции, поскольку не следует явно указывать тип возвращаемого лямбда-функции.Просто напишите что-нибудь подобное в глобальной области видимости:

 auto retFun = []() {
     return [](int x) {return x;};
 };
14 голосов
/ 18 июня 2016

Хотя вопрос специально задается о C ++ 11, для тех, кто наткнулся на это и имеет доступ к компилятору C ++ 14, C ++ 14 теперь позволяет выводить типы возврата для обычных функций. Таким образом, пример в вопросе можно настроить так, чтобы он работал так, как нужно, просто опуская предложение -> decltype ... после списка параметров функции:

auto retFun()
{
    return [](int x) { return x; }
}

Обратите внимание, однако, что это не будет работать, если в функции появится более одного return <lambda>;. Это связано с тем, что ограничение вывода типа возвращаемого значения заключается в том, что все операторы возврата должны возвращать выражения одного и того же типа, но каждый лямбда-объект задает свой уникальный тип компилятором, поэтому выражения return <lambda>; будут иметь разные типы. 1007 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...