【发布时间】:2021-10-07 19:13:42
【问题描述】:
我正在使用 C++ 中的 lambda 表达式,并尝试了一些方法来查看结果。我实际上在 CppCon Back to Basics: Lambdas from Scratch - Arthur O'Dwyer - CppCon 2019 @21:47 观看了视频并开始使用 lambdas。
举个例子,我试过这个:
#include <iostream>
using namespace std;
int g = 10;//global var 'g'
//creating lambda
auto kitten = [=] () {return g+1;};
auto cat = [g=g] () {return g+1;};
// main
int main()
{
g = 20;//modifying global variable 'g'
cout<<"kitten: "<<kitten()<<"cat: "<<cat()<<endl;
return 0;
}
以上代码的输出为:
kitten: 21cat: 11
在上面的例子中:[g=g]表示捕获一个名称为g且类型与外部g相同的数据成员,就像我写了auto g=g一样。这是g 的副本。当我们认为时这是有道理的(好像我以auto g=g 的形式写的)所以在我们的例子中结果是11,全局g 的修改不会反映在我们的local g 中。
小猫的结果是 21,因为据我了解,捕获所有内容,即按值捕获所有外部变量。
然后,当涉及到这个例子时,通过修改第一个 lambda 如下:
auto kitten = [] () {int g = g; return g+1;};
在我声明 local g 并从 global g 赋值的地方,输出是:
kitten: 1cat: 11
但我期待第一个示例 (21) 中的输出,因为我正在尝试创建一个本地 g 并从全局 g 分配它的值,它已经是修改后的值 20。
代码在https://techiedelight.com/compiler/和godbolt.org上用c++(GCC 8.3.0)编译(用最新的编译器[=]这是不允许的,但结果是一样的)。
此时,我对捕获和/或 lambda 的概念有点困惑。
【问题讨论】:
-
[g=g]与[auto g=g]相同,并且是您正在执行的操作。=表示在 lambda 捕获中复制,&表示引用。 -
@NathanOliver 除了
[auto g=g]不是真正的语法。 (如果真的需要在初始化捕获上强制使用一种类型,可以使用[v=static_cast<T>(e)]。) -
@Yakk - Adam Nevraumont 它可以从这里编译:techiedelight.com/compiler 使用 gcc 8.3.0,如帖子中所述!请仔细阅读并在那里尝试。
-
除非捕获列表为空并且 lambda 表达式的主体中没有引用外部非 constexpr 符号,否则此 lambda 会执行捕获。无捕获 lambda 表达式的一个可靠标志是它可以绑定到函数指针。
标签: c++ c++11 lambda std capture