嵌套Lambda中this指针捕获:为何内层Lambda指向X类对象?
嵌套Lambda中this指针的捕获逻辑
先直接给结论:内层Lambda的this指向X类对象,是因为你捕获的this从始至终都是X类对象的指针,和外层Lambda自身的闭包实例无关。
1. Lambda的[this]捕获到底抓的是什么?
每个Lambda都是编译器自动生成的匿名闭包类,当你在X类的成员函数func()里写[this]时,捕获的是当前X类对象的指针,不是Lambda自己的闭包实例指针。
在你的代码里:
- 外层Lambda捕获
[this]后,它的函数体内的this、x、vec全都是X类对象的成员,和外层Lambda自己没关系。 - 内层Lambda写
[this]时,它是从当前作用域(也就是外层Lambda的函数体)里拿this,而这个作用域里的this本来就是X类对象的指针,所以内层Lambda自然也指向X对象。
2. 为啥外层Lambda的this不会被内层捕获?
外层Lambda的闭包实例确实有自己的this,但这个this不会自动成为Lambda函数体内的默认this——在Lambda的函数体里,名称this优先查找外部作用域的符号。
简单说,外层Lambda的函数体里,this已经被替换成X类的指针了,内层Lambda捕获的是这个已经替换好的指针,根本碰不到外层Lambda自己的闭包实例。如果非要捕获外层Lambda的闭包,得显式写[=]或者[*this](捕获外层Lambda的拷贝),但你的场景里外层Lambda没自己的成员,这么做毫无意义。
3. 结合代码运行结果看逻辑
你的代码执行步骤:
- 调用
x.func(),外层Lambda被加入vec,它抓的是X对象x的指针。 - 执行
x.vec[0]():外层Lambda运行,++x把X的x从0改成1,然后把内层Lambda加入vec,内层Lambda同样抓X对象x的指针。 - 执行
x.vec[1]():内层Lambda运行,++x把X的x从1改成2,所以输出就是你看到的结果。
代码示例
#include <iostream> #include <functional> #include <vector> struct X { int x{}; void func() { vec.push_back([this]() { std::cout << "From outer lambda " << ++x << "\n"; vec.push_back([this]() { std::cout << "From inner lambda " << ++x << "\n"; }); }); } std::vector<std::function<void()>> vec; }; int main(int argc, char *argv[]) { X x; x.func(); x.vec[0](); x.vec[1](); }
程序输出
From outer lambda 1 From inner lambda 2
内容的提问来源于stack exchange,提问作者user3882729
相关产品推荐
相关产品推荐

