一、简介
C++11开始引入了Lambda表达式,可将lambda表达式视为包含公有operator()的匿名接口(或类),这样可以更方便的使用函数对象或创建匿名函数(类似Java的匿名内部类)。
二、Lambda表达式定义
lambda表达式的定义必须以方括号([])打头。这些方括号告诉编译器,接下来是一个lambda表达式。方括号后面是一个参数列表,该参数列表与不使用lambda表达式时提供给operator()的参数列表相同。
[capture list] (params list) mutable -> return type {
function body }
- capture list:捕获的外部变量列表,可以为空
- params list:形参列表,可以省略,表示无参函数
- mutable:mutable关键字,表示是否可以修改捕获的变量,一般用不上,可以省略
- -> return type:明确返回类型,可以省略,省略时根据函数体的return语句返回的类型确定,无return则返回类型为void
- function body:函数体,函数实现
三、capture list详解
1. [] 不捕获外部任何变量
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
auto func = [](int i) {
cout << i << endl; }; // 有一个形参i
func(i);
}
2. [=] 捕获外部作用域所有变量的值,只读无法修改
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
auto func = [=]() {
cout << i << endl; }; // 没有形参,而且直接捕获的i的值
func();
}
3. [&] 捕获外部作用域所有变量的引用,可修改捕获的变量
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
auto func = [&]() {
// 没有形参,而且直接捕获的i的引用
cout << "修改前,i = " << i << endl;
i++;
};
func();
cout << "修改后,i = " << i << endl;
}
执行结果:
修改前,i = 1
修改后,i = 2
4. [var] 只捕获外部变量var的值,只读无法修改
5. [&var] 只捕获外部变量var的引用,可修改
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
auto func = [i]() {
cout << i << endl; }; // 只捕获的i的值
func();
}
6. [this] 捕获当前类的this指针
例如:
#include <iostream>
using namespace std;
class Dog
{
public:
int age = 1;
void bark() {
cout << "汪!" << endl; };
void lambda() {
auto fun = [this] {
// 捕获this指针
this->bark(); // 通过this指针调用bark()函数
cout << "age = " << this->age << endl; // 通过this指针访问age变量
};
fun();
}
};
int main()
{
Dog dog;
dog.lambda();
}
7. [=, &] 混合方式
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
int j = 2;
// [&, =j]() { // 变量j值方式捕获,其余变量捕获引用
auto func = [=, &i]() {
// 变量i引用方式捕获,其余变量值方式捕获
cout << "j = " << j << endl;
i++;
};
func();
cout << "i = " << i << endl;
}
四、mutable关键字
mutable关键字说明函数体中可以修改值捕获的变量,但不会影响到外部变量的值,因为值传递是以拷贝的方式实现的。
例如:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
auto func = [=] () mutable {
// 不加mutable则编译报错,因为捕捉值时i是只读的
i++;
cout << "lambda内,i = " << i << endl;
};
func();
cout << "lambda外,i = " << i << endl;
}
执行结果:
lambda内,i = 2
lambda外,i = 1
五、一些场景、例子
1. 排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> nums {
3, 10, 5, 32, 1 };
sort(nums.begin(), nums.end(), [](int a, int b) -> bool {
return a < b; });
cout << "max = " << nums[4] << endl;
}
2. 递归
使用C++11新特性的function来接收lambda表达式,两者是等价的。
例如求 1 到 n 的和:
#include <iostream>
#include <functional>
using namespace std;
int main()
{
std::function<int(int)> func = [&func](int n) {
return n <= 1 ? 1 : func(n - 1) + n;
};
cout << "func(3) = " << func(3) << endl;
cout << "func(10) = " << func(10) << endl;
}
执行结果:
func(3) = 6
func(10) = 55
转载:https://blog.csdn.net/afei__/article/details/116161236
查看评论