lambda表达式——捕获

时间:2025-03-14 17:58:42
#include <iostream> #include <vector> using namespace std; class Point{ public: double x; double y; void print() const { std::cout << x<< ", "<<y<<endl;; } }; int number=100; //全局变量可以在lambda修改,跨越所有,捕获类型管理不到 int main() { Point p1{100,200}; Point p2{100,200}; //=表示值捕获,就是将外部变量拷贝进来,声明的时候,只能用auto,因为是匿名对象 //如果没有mutable,会报错,不允许修改p1,p2;如果修改捕获对象,就需要mutable auto lambda1 = [=] (int n) mutable //p1,p2为外部变量,实际调用了拷贝构造函数 { p1.x+=n; //从外部拷贝进来了,此处修改不影响外部p1 p1.y+=n; p2.x+=n; p2.y+=n; p1.print(); //print()有个const,如果此时p1,p2没修改(即上面4行不存在),如果print没有const,lambda也需要mutable(编译器认为调用函数也可能更改了) p2.print(); number++; //全局变量直接使用 }; //Lambda_Value lambda1(p1,p2); lambda1(10); //外部看不到p1,p2,打印110,210 lambda1(10); //多执行一次,会改变lambda对象内部的p1,p2,栈上的lambda对象没有销毁,120,220 p1.print(); //不改变外部的p1,p2,所以此处打印是一样的,100,200 p2.print(); cout<<sizeof(lambda1)<<endl; //没有捕获,就是一个空类,有捕获后,就有32byte cout<<sizeof(Point)<<endl; // cout<<"lambda1------------"<<endl; auto lambda2 = [&] (int n) //引用捕获,不用mutable,lambda内部修改会传递到外部 { p1.print(); p2.print(); p1.x+=n; p1.y+=n; p2.x+=n; p2.y+=n; number++; //全局的执行也有效果 }; //Lambda_Ref lambda2(p1,p2); lambda2(100);//p1,p2先打印原始值,之后 p1:200,300; p2:200,300 p1.print(); //200,300 p2.print(); p1.x+=5; // = 205 p1.y+=5; // = 305 p2.x+=5; p2.y+=5; lambda2(100); //引用捕获,外部更改也会影响引用捕获内部变量,先打印205,305,之后305,405 //return lambda2; //隐蔽错误,因为lambda2是引用捕获,函数返回后,p1,p2销毁了,值捕获就没有问题 cout<<number<<endl; //lambda内部修改此处表现出来了 cout<<sizeof(lambda2)<<endl;//只是引用,大小不计算引用参数大小 cout<<"lambda2------------"<<endl; auto lambda3 = [=, &p1] () //默认值捕获,但p1使用引用捕获 { p1.x++; p1.y++; //p1修改外部更改,306,406 p2.print(); //值捕获305,405 }; lambda3(); //auto lambda4 = [ &, &p1] () 或者 auto lambda4 = [ =, p1] () 都是重复性错误 auto lambda4 = [ &, p1] () //默认引用捕获,p1是值捕获 { p1.print(); p2.x++; //引用捕获,p2:306,406 p2.y++; }; lambda4(); // auto lambda5 = [p2, &number] () //失败,number不能 auto lambda5 = [p2] () //单独对p2值捕获 { p2.print(); //306,406 }; lambda5(); auto lambda6 = [&p1] () //单独对p1引用捕获 { p1.x++; p1.y++; }; lambda6(); }