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



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



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


ни этот:



int(int) retFun();


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

568   4  

4 ответов:

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

std::function<int (int)> retFun() {
    return [](int x) { return x; };
}

для этого простого примера вам не нужно 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; };
}

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

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

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

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

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

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

Comments

    Ничего не найдено.