[外部变量访问方式说明符] (参数) mutable noexcept/throw() -> 返回值类型
{
函数体;
};
-> 返回值类型
。[]{}
显然,此 lambda 匿名函数未引入任何外部变量([] 内为空),也没有传递任何参数,没有指定 mutable、noexcept 等关键字,没有返回值和函数体。所以,这是一个没有任何功能的 lambda 匿名函数。外部变量格式 | 功能 |
---|---|
[] | 空方括号表示当前 lambda 匿名函数中不导入任何外部变量。 |
[=] | 只有一个 = 等号,表示以值传递的方式导入所有外部变量; |
[&] | 只有一个 & 符号,表示以引用传递的方式导入所有外部变量; |
[val1,val2,...] | 表示以值传递的方式导入 val1、val2 等指定的外部变量,同时多个变量之间没有先后次序; |
[&val1,&val2,...] | 表示以引用传递的方式导入 val1、val2等指定的外部变量,多个变量之间没有前后次序; |
[val,&val2,...] | 以上 2 种方式还可以混合使用,变量之间没有前后次序。 |
[=,&val1,...] | 表示除 val1 以引用传递的方式导入外,其它外部变量都以值传递的方式导入。 |
[this] | 表示以值传递的方式导入当前的 this 指针。 |
#include <iostream> #include <algorithm> using namespace std; int main() { int num[4] = {4, 2, 3, 1}; //对 a 数组中的元素进行排序 sort(num, num+4, [=](int x, int y) -> bool{ return x < y; } ); for(int n : num){ cout << n << " "; } return 0; }程序执行结果为:
1 2 3 4
程序第 9 行通过调用 sort() 函数实现了对 num 数组中元素的升序排序,其中就用到了 lambda 匿名函数。而如果使用普通函数,需以如下代码实现:#include <iostream> #include <algorithm> using namespace std; //自定义的升序排序规则 bool sort_up(int x,int y){ return x < y; } int main() { int num[4] = {4, 2, 3, 1}; //对 a 数组中的元素进行排序 sort(num, num+4, sort_up); for(int n : num){ cout << n << " "; } return 0; }此程序中 sort_up() 函数的功能和上一个程序中的 lambda 匿名函数完全相同。显然在类似的场景中,使用 lambda 匿名函数更有优势。
#include <iostream> using namespace std; int main() { //display 即为 lambda 匿名函数的函数名 auto display = [](int a,int b) -> void{cout << a << " " << b;}; //调用 lambda 函数 display(10,20); return 0; }程序执行结果为:
10 20
可以看到,程序中使用 auto 关键字为 lambda 匿名函数设定了一个函数名,由此我们即可在作用域内调用该函数。#include <iostream> using namespace std; //全局变量 int all_num = 0; int main() { //局部变量 int num_1 = 1; int num_2 = 2; int num_3 = 3; cout << "lambda1:\n"; auto lambda1 = [=]{ //全局变量可以访问甚至修改 all_num = 10; //函数体内只能使用外部变量,而无法对它们进行修改 cout << num_1 << " " << num_2 << " " << num_3 << endl; }; lambda1(); cout << all_num <<endl; cout << "lambda2:\n"; auto lambda2 = [&]{ all_num = 100; num_1 = 10; num_2 = 20; num_3 = 30; cout << num_1 << " " << num_2 << " " << num_3 << endl; }; lambda2(); cout << all_num << endl; return 0; }程序执行结果为:
lambda1:
1 2 3
10
lambda2:
10 20 30
100
auto lambda1 = [=]() mutable{ num_1 = 10; num_2 = 20; num_3 = 30; //函数体内只能使用外部变量,而无法对它们进行修改 cout << num_1 << " " << num_2 << " " << num_3 << endl; };由此,就可以在 lambda1 匿名函数中修改外部变量的值。但需要注意的是,这里修改的仅是 num_1、num_2、num_3 拷贝的那一份的值,真正外部变量的值并不会发生改变。
#include <iostream> using namespace std; int main() { auto except = []()throw(int) { throw 10; }; try { except(); } catch (int) { cout << "捕获到了整形异常"; } return 0; }程序执行结果为:
捕获到了整形异常
可以看到,except 匿名数组中指定函数体中可以抛出整形异常,因此当函数体中真正发生整形异常时,可以借助 try-catch 块成功捕获并处理。#include <iostream> using namespace std; int main() { auto except1 = []()noexcept{ throw 100; }; auto except2 = []()throw(char){ throw 10; }; try{ except1(); except2(); }catch(int){ cout << "捕获到了整形异常"<< endl; } return 0; }此程序运行会直接崩溃,原因很简单,except1 匿名函数指定了函数体中不发生任何异常,但函数体中却发生了整形异常;except2 匿名函数指定函数体可能会发生字符异常,但函数体中却发生了整形异常。由于指定异常类型和真正发生的异常类型不匹配,导致 try-catch 无法捕获,最终程序运行崩溃。
本文链接:http://task.lmcjl.com/news/18569.html