C++ lambda表达式 - 编译器如何解释它们?

MS *_*nth 8 c++ lambda c++11

我刚开始学习C++ 11中的新功能.我正在阅读C++ Primer(Stanley Lippman)中的lambdas并正在尝试它们.

我尝试了以下代码:

auto func() -> int (*) (){
    //int c=0;
    return []()-> int {return 0;};
}

int main(){
    auto p = func();
}
Run Code Online (Sandbox Code Playgroud)

这段代码编译得很好.所以我猜没有任何捕获的lambdas只是由编译器生成为普通函数,我们可以使用它们的普通函数指针.

现在我更改了代码以使用捕获:

auto func() -> int (*) (){
    int c=0;
    return [=]()-> int {return c;};
}

int main(){
    auto p = func();
}
Run Code Online (Sandbox Code Playgroud)

但这无法编译.使用g ++时出现以下编译错误:

main.cpp: In function ‘int (* func())()’:
main.cpp:6:31: error: cannot convert ‘func()::__lambda0’ to ‘int (*)()’ in return
return [=]()-> int {return c;};
Run Code Online (Sandbox Code Playgroud)

从错误中我可以理解,它不是生成的普通函数,它可能是一个带有重载调用操作符的类.或者是别的什么?

我的问题:编译器如何在内部处理lambdas?我应该如何传递使用捕获的lambda,即func()的返回值应该是什么?我目前无法想到一个用例,我需要使用这样的lambdas,但我只是想了解更多关于它们的信息.请帮忙.

谢谢.

jro*_*rok 9

所有lambda都是具有实现定义类型的函数对象,称为带有成员的闭包类型operator().每个lambda表达式都有自己独特的闭包类型.

没有捕获的Lambda可以转换为函数指针.编译器是否在幕后生成正常函数是一个内部细节,对您来说无关紧要.

无法返回在函数内定义的lambda.很少有东西阻止这种情况 - 你不知道一种lambda表达式的名称,你不能在a里面使用lambda表达式decltype,并且如前所述,两个lambda表达式(即使词法相同)具有不同的类型.

你可以做的是使用std::function:

std::function<int()> func()
{
    int i = 0;
    return [=]()-> int {return i;};
}
Run Code Online (Sandbox Code Playgroud)

这种方式也适用于捕获.

或类似的东西:

auto f = []{ return 0; };

auto func() -> decltype(f)
{
    return f;
}
Run Code Online (Sandbox Code Playgroud)

编辑:然而,即将推出的C++ 1y标准(更具体地说,返回类型扣除)将允许您这样做:

auto func()
{
    int i = 42;
    return [=]{ return i; };   
}
Run Code Online (Sandbox Code Playgroud)

  • 提到转换为函数指针的唯一答案!?? +1请注意,您可以从lambda返回lambda,在C++中也可以从函数返回,通过返回类型推导.lambda表达式的类型*never*是任何可观察行为的函数类型(当然,它通常实现为(成员)函数).例如,保证lambda与模板类型推导中的一些通用`Ret(Params ...)`不匹配. (2认同)