um1 << ',' << num2 << endl;};
num1 = 19;
num2 = 27;
func();
return 0;
}
//结果
//19,27
4. 混合方式
上面的例子,要么是值捕获,要么是引用捕获,Lambda表达式还支持混合的方式捕获外部变量,这种方式主要是以上几种捕获方式的组合使用。
示例:
#include <iostream>
using namespace std;
#define p 12
int main()
{
int num1 = 17 , num2 = 21;
auto func = [num1,&num2](){cout << num1 << ',' << num2 << endl;};
num1 = 19;
num2 = 27;
func();
return 0;
}
//结果
//17,27
C++11中的lambda表达式捕获外部变量的主要形式
捕获形式 |
具体说明 |
[] |
不捕获任何外部变量 |
[变量名,...] |
默认以值捕获指定的多个变量,如果引用捕获,需显示声明(&) |
[this] |
以值捕获this指针 |
[=] |
以值捕获所有需要的外部变量,包括this指针 |
[&] |
以引用捕获所有需要的外部变量,包括this指针 |
[=,&num1,&num2] |
以引用捕获变量num1、num2,其余变量以值捕获 |
[&,num1,num2] |
以值捕获变量num1、num2,其余变量以引用捕获 |
mutable指示符——修改捕获变量
前面有提到,在lambda表达式中,如果以值传递捕获外部变量,则函数体中不能修改该外部变量,否则会编译错误
通过使用mutable关键字,用以说明表达式的函数体可以修改值捕获的变量
示例:
#include <iostream>
using namespace std;
int main()
{
int num1 = 17 , num2 = 21;
auto func = [=]()mutable{cout << ++num1 << ',' << ++num2 << endl;};
num1 = 19;
num2 = 27;
func();
return 0;
}
//结果
//18,22
lambda表达式的参数列表
lambda表达式的参数与普通函数的参数类似,但在lambda表达式中传递参数存在着一些限制,主要有以下几点
- 参数列表中不能有默认参数
- 不支持可变参数
- 所有参数必须有参数名
lambda表达式的原理
实际上编译器在全局作用域自动生成了一个类,在类中重载了operator(),operator()函数的内容就是lambda表达式的内容。
故可以理解为lambda表达式本质上还是仿函数,是一个编译器自动生成的仿函数。
lambda表达式与STL
lambda表达式的引入为STL的使用带来了极大的便利,我们可以在泛型算法中提供lambda表达式作为谓词函数进行某些操作
示例(统计元素和):
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> nums{1, 2, 3, 4, 5, 6, 7, 8, 9};
int sum = 0;
for_each(nums.begin(), nums.end(), [&sum](int val)
{ sum += val; });
cout << sum << endl;
return 0;
}
//结果
//45