C++11 Lambda捕获:如何同时捕获this并按值捕获所有局部变量?
解决C++11中Lambda同时捕获
this和所有局部变量的问题 你遇到的这个编译错误是因为C++11标准不允许混合默认值捕获(=)和显式的this捕获,反过来[=, this]也不行——这是早期Lambda语法的一个限制。不过有两种办法可以完美解决你的需求:
方法1:C++11兼容的写法(无需升级标准)
在成员函数里,先把this赋值给一个局部变量,然后用[=]默认值捕获所有局部变量(包括这个存了this的变量):
class Foo { int x, y, z; std::function<void(void)> _func; // ... void bar() { int a,b,c; auto self = this; // 将this存储到局部变量中 // ... _func = [=]() { // 默认值捕获所有局部变量,包括self int u = self->x + a; // 通过self访问类成员变量 // ... }; } };
这种写法的本质是把this转换成一个普通局部变量,让[=]可以一并捕获,既实现了对类实例变量的访问,又自动捕获了所有局部变量的值。
方法2:升级到C++14及以后
从C++14开始,标准放宽了Lambda捕获的规则,允许你直接混合默认捕获和this捕获,不管顺序是[this, =]还是[=, this]都可以正常编译:
class Foo { int x, y, z; std::function<void(void)> _func; // ... void bar() { int a,b,c; // ... _func = [=, this]() { // C++14及以后支持的写法 int u = this->x + a; // ... }; } };
如果你的项目环境允许升级C++标准,这是最直接简洁的解决方案。
需要额外提醒的是:不管用哪种写法,捕获this(或self)意味着Lambda会持有类实例的指针,一定要小心悬空指针/引用的问题——如果Lambda的生命周期超过了类实例的生命周期,访问self->x会导致未定义行为。
内容的提问来源于stack exchange,提问作者wcochran
相关产品推荐
相关产品推荐

