1.定义:C++中创建匿名函数(不带名字的函数)使用Lambda表达式,Lambda表达式允许我们在需要函数对象的地方定义和简短的使用函数,而无需显示定义具体名的函数
定义一个匿名函数一共有三步
①[] 使用匿名函数外部函数定义的变量,例如i变量,但是在匿名函数内部不允许修改,若要强制修改,用引用,需变为[&i]。 若外部的所有变量都想在匿名函数里边仅使用,变为[=]。若想改变值则变为[&]。 [=,&j]表示除了j是引用之外,其它变量是值传递
②() 传入形参,例如(int a ,int b)
③{} 代码编写
1.1 表达式语法:[捕获列表] (参数列表) -> 返回值类型 {函数体}
注:在编写Lambda表达式的时候,可以忽略参数列表和返回值类型,但是捕获列表和函数体必须包含,其中[ ] 不能省略,编译根据它来识别后面是否是Lambda表达式,并且它还有一个作用就是能够让Lambda的函数体访问它所处作用域的成员。
1.2示例
#include <iostream>
using namespace std;
int main() {
//示例1-加法
[](int a, int b)->int {
return a+b ;
};
//示例2-如果编译器能够推断出来类型,则->也可以省略
[](int a, int b) {
return a+b ;
};
//示例3-一个最简单的lambda表达式
[] () {};
return 0;
}
1.3 捕获列表的说明
Lambda表达式需要在函数体中定义,这时如果想访问所处函数中的某个成员,那么就需要使用捕获列表了。捕获列表的写法通常有以下几种形式:
形式 | 作用 | |||
[a] | 表示值传递方式捕获a | |||
[=] | 表示值传递方式捕获所有父作用域所有变量(包括this) | |||
[&a] | 表示引用传递方式捕获变量a | |||
[&] | 表示引用传递方式捕获所有父作用域所有变量(包括this) | |||
[this] | 表示值传递方式捕获当前的this指针 | |||
[=,&a,&b] | 通过引用方式捕获a和b,值传递方式捕获其它变量 |
2.Lambda表达式的使用
Lambda表达式定义出来并不会自己调用,而是要进行手动调用,调用方式包括两种
- 使用变量接收,然后再调用
int main() {
int i = 100;
int j = 200;
//使用变量接受然后再调用
//定义了一个匿名函数,让c变量保存了这个函数
auto c = [&i,&j](int a,int b) ->int { //->int 表示返回值的类型为int型
i = 1; //对i和J使用了引用,可以在匿名函数中修改值
cout << "i=" << i << endl;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
return 45;
};
//c变量保存了匿名函数,所以c()就相当于调用了这个函数,67,98是实参
int ref = c(67,98);
cout << "i=" << i << endl;
cout << "ref" << ref << endl;
}
运行结果:
- 不使用变量接受直接调用,在{}后边添加一个()
int main() {
//定义了一个匿名函数,不接受表达式直接引用
int A = [&](int m,int n)->int{
return m+n;
}(123,456); //()调用匿名函数
cout << "A=" << A << endl;
cout << "-----------------" << endl;
return 0;
}
运行结果:
3.Lambda的应用场景
编写Lambda表达式很简单,但是用得上Lambda表达式比较特殊。在C++内部,函数的内部不允许再定义函数,如果函数中需要使用到某一个函数帮助计算并返回结果,代码又不是很多,那么Lambda表达式不失为一种上佳选择。如果没有Lambda表达式,那么必须在函数的外部去定义一个内联函数。来回查看代码比较拖沓,定义Lambda函数,距离近些,编码效率高些,对于计算机来说不用开辟新的内存去存放内联函数。