C++ 返回 lambda 表达式的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4726768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:17:00  来源:igfitidea点击:

Function returning a lambda expression

c++functionc++11lambda

提问by Bartosz Milewski

I wonder if it's possible to write a function that returns a lambda function in C++11. Of course one problem is how to declare such function. Each lambda has a type, but that type is not expressible in C++. I don't think this would work:

我想知道是否可以在 C++11 中编写一个返回 lambda 函数的函数。当然,一个问题是如何声明这样的函数。每个 lambda 都有一个类型,但该类型在 C++ 中无法表达。我认为这行不通:

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

Nor this:

也不是这个:

int(int) retFun();

I'm not aware of any automatic conversions from lambdas to, say, pointers to functions, or some such. Is the only solution handcrafting a function object and returning it?

我不知道从 lambdas 到函数指针的任何自动转换,或者一些这样的。手工制作函数对象并返回它的唯一解决方案是什么?

回答by Sean

You don't need a handcrafted function object, just use std::function, to which lambda functions are convertible:

您不需要手工制作的函数对象,只需使用std::function, lambda 函数可以转换为:

This example returns the integer identity function:

此示例返回整数标识函数:

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

回答by user534498

For this simple example, you don't need std::function.

对于这个简单的例子,你不需要std::function.

From standard §5.1.2/6:

来自标准 §5.1.2/6:

The closure type for a lambda-expressionwith no lambda-capturehas a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type's function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type's function call operator.

没有lambda 捕获lambda 表达式的闭包类型具有公共非虚拟非显式 const 转换函数,指向与闭包类型的函数调用运算符具有相同参数和返回类型的函数的指针。此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果。

Because your function doesn't have a capture, it means that the lambda can be converted to a pointer to function of type int (*)(int):

因为您的函数没有捕获,这意味着可以将 lambda 转换为指向类型为函数的指针int (*)(int)

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

That's my understanding, correct me if I'm wrong.

这是我的理解,如有不对请指正。

回答by dzhioev

You can return lambda function from other lambda function, since you should not explicitly specify return type of lambda function. Just write something like that in global scope:

您可以从其他 lambda 函数返回 lambda 函数,因为您不应显式指定 lambda 函数的返回类型。只需在全局范围内编写类似的内容:

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

回答by Anthony Hall

Though the question specifically asks about C++11, for the sake of others who stumble upon this and have access to a C++14 compiler, C++14 now allows deduced return types for ordinary functions. So the example in the question can be adjusted just to work as desired simply by dropping the -> decltype... clause after the function parameter list:

尽管该问题专门询问了 C++11,但为了其他偶然发现并可以访问 C++14 编译器的人,C++14 现在允许为普通函数推导返回类型。因此,只需-> decltype在函数参数列表之后删除... 子句,就可以调整问题中的示例以使其按需要工作:

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

Note, however, that this will not work if more than one return <lambda>;appears in the function. This is because a restriction on return type deduction is that all return statements must return expressions of the same type, but every lambda object is given its own unique type by the compiler, so the return <lambda>;expressions will each have a different type.

但是请注意,如果return <lambda>;函数中出现多个,这将不起作用。这是因为对返回类型推导的限制是所有 return 语句必须返回相同类型的表达式,但是编译器为每个 lambda 对象赋予了自己的唯一类型,因此return <lambda>;每个表达式将具有不同的类型。

回答by Terens Tare

You should write like this:

你应该这样写:

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

to get your return as a function, and use it like:

将您的回报作为一个函数,并像这样使用它:

int val = returnFunction(someNumber);