1.Lambda函数介绍
Lambda 表达式因数学中的演算得名,直接对应于其中的 lambda 抽象。Lambda 表达式能够捕获作用域中的变量的无名函数对象。我们可以将其理解为一个匿名的内联函数,可以用来替换独立函数或者函数对象,从而使代码更可读。但是从本质上来讲,Lambda 表达式只是一种语法糖,因为它能完成的工作也可以用其他复杂的 C++ 语法来实现。
2. Lambda基本语法
下面是Lambda语句的基本语法:
1
| [capture] (parameters) mutable -> return-type {statement}
|
由此,我们可以写一个Lambda表达式:
1 2 3
| int foo = [](int a, int b) -> int { return a+b; };
|
1. 对lambda表达式各部分解释
- capture 用于指定捕获哪些变量,以及捕获是通过值还是引用:
- [] 不捕获任何变量
- [var] 以值传递方式捕获变量var(lambda中不能修改var)
- [&var] 以引用传递方式捕获变量var
- [&] 以引用传递方式捕获父作用域的所有变量(包括this)
- [=] 以值传递方式捕获父作用域的所有变量(包括this)
- [&, =var] 以值传递方式捕获变量var,其他变量以引用传递方式捕获
- [=, &var] 以引用传递方式捕获变量var,其他变量以值传递方式捕获
- [this] 以值传递方式捕获当前this指针
- parameters 参数列表,与普通函数一致,如若无需传递参数括号内可为空或可直接连同括号一起省略
- mutable 可选,如若指定mutable,则会在函数体内拷贝以值传递方式捕获的变量,并允许在函数体内更改变量的值且不会更改父作用域里该变量的值
- -> return-type 返回值类型,若无返回值可直接省略,若有返回值,也可省略由编译器推导
- statement 函数体,可直接使用参数和捕获的变量
lambda中除捕获列表和函数体是必需的,其它都是可选的,最简的lambda是[] {}
,但是该lambda无法处理任何事
3. Lambda的使用
1. 无效lambda
1 2 3 4 5
| int a = 10; int b = 10;
[=] { std::cout << a+b << std::endl; };
|
2. 将lambda赋值给一个变量直接调用
1 2 3 4 5
| auto foo = [](int a, int b) -> int { return a+b; }; std::cout << foo(10, 10) << std::endl;
|
3. 以值传递方式捕获父作用域变量
1 2 3 4 5 6 7 8 9 10
| int a = 10; int b = 10;
auto foo = [a] (int x) -> int { x += 10; return a+x; };
std::cout << foo(b) << std::endl;
|
使用mutable:
1 2 3 4 5 6 7 8 9 10 11 12
| int a = 10; int b = 10;
auto foo = [=] mutable -> int { a += 10; b += 10; return a+b; };
std::cout << foo() << std::endl; std::cout << a << " " << b << std::endl;
|
4. 以引用传方式捕获变量
1 2 3 4 5 6 7 8 9 10 11 12
| int a = 10; int b = 10;
auto foo = [&] -> int { a += 10; b += 10; return a+b; };
std::cout << foo << std::endl; std::cout << a << " " << b << std::endl;
|
5. 自定义排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <iostream> #include <vector> #include <algorithm>
int main() { std::vector<int> arr;
for (int i = 0; i < 10; i++) { arr.push_back(rand()); }
std::sort(arr.begin(), arr.end(), [](int a, int b) {return a > b;});
for (auto i = arr.begin(); i != arr.end(); i++) { std::cout << *i << std::endl; }
return 0; }
|