Подтвердить что ты не робот

Функция, возвращающая лямбда-выражение

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

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

И это:

int(int) retFun();

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

4b9b3361

Ответ 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);