1.构成lambad表达式的几个重要部分
lambad表达式的形式:[]()->return_type {}
- [ ]:捕获外部变量;
[]:不捕获任何外部变量
[=]:以传值的方式捕获外部变量
[&]:以传引用的方式捕获外部变量
[this]:如果是在类的成员方法中的话,可以捕获this指针
[=,&a]:a以引用的方式捕获,其他都以值传递的方式进行捕获
[a,&b]:a以传值的方式进行捕获,b以传引用的方式进行捕获
- ():lambad表达式的参数列表;
- -> return_type :表达式的返回值类型,如果是void,->return_type这部分可以省略不写;
- {}:中是lambad的操作代码。
2.lambad表达式的使用
int main() {
auto lam1 = []()->void { cout << "this is lambad exp1" << endl; };
//无需返回值,可以省略不写
auto lam2 = [](){ cout << "this is lambad exp2" << endl; };
lam1();
lam2();
auto lam3 = [](int a, int b) ->int { return a + b; };
cout << lam3(1, 99) << endl;
int x = 999;
auto lam4 = [=](int y)->int { return x + y; };
cout << lam4(1) << endl;
int z = 10000;
int j = 99999999;
auto lam5 = [&z, j]()mutable {z = 0; j = 0; };
lam5();
cout << "z = " << z << "j = " << j << endl;
return 0;
}
执行结果:
this is lambad exp1
this is lambad exp2
100
1000
z = 0 j = 99999999
3.实际上,lambad是operator(),只不过这个类由编译器给我们生成,不用我们写
规则如下:
[]:对应类的成员变量 和 构造函数的参数列表
():对应给类的operator()传递的参数
-> retutn_type返回值:指的是operator()的返回值
{} :函数体指的是operator()的函数题
其中,operator()是一个const方法,但是可以给lambad表达式()后面加mutable使失去const性质
下面拿几个lambad表达式以及其编译器给我们生成的类作解释:
- 文件操作的lambad
const string path = "./";
auto fileop = [path](std::string filename)->FILE*{
std::string fullpath = path+filename;
return fopen(fullpath.c_str(),"w");
};
//对应的类为
class fileop1{
public:
fileop1(const string path):path_(path){}
FILE *operator()(std::string filename){
std::string fullname = path_ + filename;
return fopen(fullname.c_str(),"w");
}
private:
std::string path_;
};
- 比较两个整形值的大小
auto com = [x,y]()->bool{
return x > y;
};
//对应的类为
template <typename Ty = int>
class Com1{
public:
Com1(Ty a,Ty b):ma(a),mb(b){}
bool operator()()const{
return ma > mb;
}
private:
Ty ma;
Ty mb;
};
- 求解四个整形值的和
auto add1 = [](int a = -1,int b = -1,int c = -1,int d = -1)->int{
return a+b+c+d;
};
//对应的类是
template <typename Ty = int>
class Add1{
public:
Add1(){}
int operator()(Ty a,Ty b,Ty c,Ty d)const{
return a+b+c+d;
}
};
4.总结:
- lambad表达式实际上也是operator()运算重载,只不过我们程序猿不需要自己去实现对应的类,由编译器给我们生成,使用时,实际上我们调用的是对象的operator();
- lambad表达式的生命周期为当前语句,所以我们一般和
std::function
搭配使用,将lambad表达式的类型保留下来; - 由于默认生成的operator()是一个常方法,所以,如果我们需要在operator()中修改值,需要这样写:
[]()mutable -> type {}
,添加mutable。