Overview
1.cpp Lambda 表达式的语法
2.capture List 捕获列表
cpp Lambda 表达式的语法
1.Lambda 表达式为cpp引入匿名函数, 和 python 的lambda函数做的事一样, 匿名函数的存在可以允许我们不给函数起名使得代码非常紧凑;
2.Lambda 表达式将函数名称被省略了, 返回值使用了一个很形象的单箭头 -> 的形式来写, 语法如下:
[capture list] (parameter list) mutable(optional) exception attribute -> return_type {
// function body
}
实际开发中最常见以下2种
[capture list] (parameter list) {function body}
[capture list] {function body}
上面的语法除了[capture list] (捕获列表) 外, 其他部分都容易理解, 先写一个基础的例子感受下lambda对于代码的简化;
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int& lhs, int& rhs) {
return lhs < rhs;
}
int main() {
vector<int> v1{3, 2, 5, 7, 4, 1};
vector<int> v2(v1);
sort(v1.begin(), v1.end(), cmp);
cout << "ori func: ";
for (auto& e : v1) {
cout << e << ' ';
}
cout << endl;
sort(v2.begin(), v2.end(), [](int& lhs, int& rhs) -> bool {
return lhs < rhs;
});
cout << "lambda: ";
for (auto& e : v2) {
cout << e << ' ';
}
cout << endl;
return 0;
}
capture List 捕获列表
1.所谓捕获列表, 可以理解为参数的一种类型; Lambda 表达式内部函数体在默认情况下是不能使用函数体外部的变量的, 这时候捕获列表可以起到传递外部数据的作用; 根据传递的行为不同, 捕获列表也分为几种: 值捕获/引用捕获/隐式捕获
2.value capture (值捕获)
(i). 值捕获类似于函数参数传递中的值传递, 被捕获的变量通过值copy的方式传入
(ii). 被捕获的变量在lambda表达式被创建的时候 copy, 而不是调用的时候发生 copy
(iii). 值捕获不能在lambda 函数体中修改捕获的变量值
#include <iostream>
using namespace std;
int main() {
int a = 123;
auto f = [a] {
a = 234; // error: cannot assign to a variable captured by copy in a non-mutable lambda
cout << a << endl;
};
a = 321;
f(); // 输出:123
}
3.reference capture (引用捕获): 引用捕获与 pass by reference 类似, 采用引用捕获值会发生变化;
#include <iostream>
using namespace std;
int main() {
int a = 123;
auto f = [&a] {
cout << a << endl;
};
a = 321;
f(); // 输出:321
}
从值捕获改为引用捕获之后, 值可以在 lambda 函数体中发生修改
#include <iostream>
using namespace std;
int main() {
int a = 123;
auto f = [&a] {
a = 234; // 这里可以发生值的修改
cout << a << endl;
};
a = 321;
f(); // 输出:234
}
4.implicit capture (隐式捕获): 手动写捕获列表有时候非常复杂, 这种机械的工作可以交给编译器来处理, 这是时候可以在捕获列表里面写一个 & 或者 写一个 = 向编译器生命采用引用捕获活着值捕获; 常用的可能是以下几种
[] // 空捕获列表
[name1, name2] 捕获一系列变量
[&] 引用捕获, 让编译器以引用形式捕获所有外部变量
[=] 值捕获, 让编译器以只的形式捕获所有外部变量
[=, &x] 变量x以引用的形式捕获, 其余变量以传值形式捕获;
[&, x] 变量x以值的形式捕获, 其余变量以引用捕获
举例如下:
#include <iostream>
using namespace std;
int main() {
int a = 123;
auto f = [&] {
cout << a << endl;
};
f();
int b = 234;
auto f2 = [&a, &b] {
cout << a << " " << b << endl;
};
f2();
return 0;
}
Reference
1.https://www.cnblogs.com/DswCnblog/p/5629165.html. C++ 11 Lambda表达式.
2.https://changkun.de/modern-cpp/en-us/03-runtime/#Basics. Modern C++ Tutorial.
转载请注明来源, from goldandrabbit.github.io