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

2023-12-21

我刚刚开始学习 C++ 11 中的新功能。我正在阅读 C++ Primer (Stanley Lippman) 中有关 lambda 的内容,并正在尝试使用它们。

我尝试了以下代码:

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

int main(){
    auto p = func();
}

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

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

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

int main(){
    auto p = func();
}

但这无法编译。我在使用 g++ 时遇到以下编译错误:

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

从错误中我可以了解到它不是生成的正常函数,它可能是一个具有重载调用运算符的类。或者是别的什么?

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

Thanks.


所有 lambda 都是函数对象,其实现定义的类型称为闭合类型 with a operator()成员。每个 lambda 表达式也有其自己独特的闭包类型。

没有捕获的 Lambda 可以是转换的到函数指针。编译器是否在幕后生成正常函数是内部细节,对您来说不重要。

不可能返回在函数内部定义的 lambda。有一些事情可以阻止这种情况 - 您不知道 lambda 表达式类型的名称,也不能在 a 中使用 lambda 表达式decltype正如已经说过的,两个 lambda 表达式(即使在词法上相同)具有不同的类型。

你能做的就是使用std::function:

std::function<int()> func()
{
    int i = 0;
    return [=]()-> int {return i;};
}

这种方式也适用于捕获。

或者是这样的:

auto f = []{ return 0; };

auto func() -> decltype(f)
{
    return f;
}

编辑:但是,即将推出的 C++1y 标准(更具体地说,返回类型推导)将允许您执行此操作:

auto func()
{
    int i = 42;
    return [=]{ return i; };   
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ lambda 表达式 - 编译器如何解释它们? 的相关文章

随机推荐