公司动态
lambda表达式的使用(3)
这次主要讲c17以前和c20中lambda表达式引用捕获的区别[this] 捕获当前类中的 this 指针让 lambda 拥有和当前类成员函数同样的访问权限。类的非静态成员变量如 int value;本身是“悬空”的必须通过 this-value 才能访问到具体对象的那块内存。[this] 把当前对象的地址复制进闭包所以 Lambda 函数体内部写 value 时编译器会翻译成 this-value。访问权限因为 Lambda 定义在成员函数内部它拥有和该成员函数完全相同的访问级别。哪怕是 private 或 protected 成员Lambda 内部也能随意读写class MyClass { private: int secret 10; public: void test() { auto f [this]() { secret 20; // 编译器翻译为 this-secret 20; }; } };如果已经使用了 或者 就默认添加此选项旧标准 C17 及以前。当你写 []按值捕获所有外部变量或 []按引用捕获所有外部变量时编译器为了让你在 Lambda 里方便地访问成员变量偷偷地把 this 也自动加进去了。实际效果你写的是 []编译器实际处理时把它当作 [, this] 来生成闭包。class MyClass { int value 10; public: void test() { // 以下两行在 C17 及以前是等价的 auto f1 []() { return value; }; // 编译器偷偷加了 this auto f2 [, this]() { return value; }; // 显式写出 } };捕获 this 的目的是可以在 lambda 中使用当前类的成员函数和成员变量。如果没有 thisLambda 函数体内写 value 或 getValue() 时会报错找不到标识符。因为 Lambda 是一个独立的局部函数对象它不知道外面的 value 属于哪个对象。捕获 this 后它就能通过 this 指针找到当前对象从而调用成员函数和读写成员变量。现代c正确写法class MyClass { int value 10; public: void test() { // ❌ C20 会发出弃用警告 // auto f1 []() { return value; }; // ✅ 显式捕获 this推荐 auto f2 [this]() { return value; }; // ✅ 如果非要用 []必须显式加上 this auto f3 [, this]() { return value; }; } };在旧标准C17前下为了让 Lambda 能像普通函数一样使用类的成员编译器会在你写 [] 时默认把 this 也带上。但现在C20这条默认规则已弃用必须自己明确写简而言之在c20里面如果要加等号但是不加this是不是就无法使用类中的成员这样如果lambda表达式中有关于类的操作就会错误