理解
Lambda表达式又称为匿名函数,在C#和python中已经有了,C++11才开始。
声明格式:
[capture list] (params list) mutable exception-> return type { function body }
其中:
- capture list:捕获外部变量列表
- params list:形参列表
- mutable指示符:用来说用是否可以修改捕获的变量
- exception:异常设定
- return type:返回类型
- function body:函数体
其他格式:
- [capture list] (params list) -> return type {function body}
- [capture list] (params list) {function body}//返回类型可以根据return猜测,如果猜测不出返回类型则为void
- [capture list] {function body}//类似于无参函数
初尝试
(sort使用):
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
return a < b;
}
int main()
{
vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
vector<int> lbvec(myvec);
sort(myvec.begin(), myvec.end(), cmp); // 旧式做法
cout << "predicate function:" << endl;
for (int it : myvec)
cout << it << ' ';
cout << endl;
sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; }); // Lambda表达式
cout << "lambda expression:" << endl;
for (int it : lbvec)
cout << it << ' ';
}
不同捕获形式:
值捕获
捕获后不能改变值; 被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。
#include <iostream>
using namespace std;
int main()
{
int a = 123;
auto f = [a] { cout << a << endl; };//不能改变lambda里面的a值
a = 321;
f(); // 输出:123
return 0;
}
引用捕获
捕获后可以改变它的值,同时后面修改捕获值也会对它造成影响
#include <iostream>
using namespace std;
int main()
{
int a = 123;
auto f = [&a] { cout << a << endl; };
a = 321;
f(); // 输出:321
}
隐式捕获:
编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=]和[&]。[=]表示以值捕获的方式捕获外部变量,[&]表示以引用捕获的方式捕获外部变量。
隐式值捕获:
#include <iostream>
using namespace std;
int main()
{
int a = 123;
auto f = [=] { cout << a << endl; }; // 隐式值捕获
f(); // 输出:123
}
隐式引用捕获:
int main()
{
int a = 123;
auto f = [&] { cout << a << endl; }; // 隐式引用捕获
a = 321;
f(); // 输出:321
}
mutable:可以修改值捕获的值:
#include <iostream>
using namespace std;
int main()
{
int a = 123;
auto f = [a]()mutable { cout << ++a; }; // 不会报错
cout << a << endl; // 输出:123,值捕获,不影响后面的值
f(); // 输出:124
}