C++ lamda表达式
lamda表达式是C++11中的新特征,说白了就是匿名函数。
lambda表达式的具体形式如下:
[capture list] (params list) mutable exception-> return type { function body }
例:
各项具体含义如下
- capture list:捕获外部变量列表,即需要用到的外部变量。
- params list:形参列表
- mutable指示符:用来说用是否可以修改捕获的变量
- exception:异常设定
- return type:返回类型
- function body:函数体
此外,我们还可以省略其中的某些成分来声明“不完整”的Lambda表达式,常见的有以下几种:
序号 | 格式 |
---|---|
1 | [capture list] (params list) -> return type {function body} |
2 | [capture list] (params list) {function body} |
3 | [capture list] {function body} |
其中:
- 格式1声明了const类型的表达式,这种类型的表达式不能修改捕获列表中的值。
- 格式2省略了返回值类型,但编译器可以根据以下规则推断出Lambda表达式的返回类型:
(1):如果function body中存在return语句,则该Lambda表达式的返回类型由return语句的返回类型确定;
(2):如果function body中没有return语句,则返回值为void类型。
- 格式3中省略了参数列表,类似普通函数中的无参函数。
来个最简单的:
[](){};
”[ ]"表示不需要使用外部变量,”( )"表示形参列表为空,"{ }"表示空函数,什么都不干。
再举一个例子。
在STL中有一个排序函数std::sort,如果现在我们要用它来按降序排列一个数组arr,则可自定义一个比较函数cmp,并把它传给sort函数,如下:
bool cmp(int a, int b)
{
return a > b;
}
std::sort(arr, arr + len, cmp);
如果使用lamda表达式,则可改写成如下
std::sort(arr, arr + len, [](int a, int b)
{
return a > b;
});
"[ ]"明没有用到外部变量,如果我们要用到外部变量,则要对"[ ]"进行修改,如下代码
int n = 10;
[](int a) {return a + n;}; // 报错,提示变量n不能在lamda体中调用,除非其在捕获列表中
"[ ]"捕获列表是指,如果我们想要访问n,在"[ ]"中加上n即可。如下
int n = 10;
[n](int a) {return a + n;}; // 正确
"[ n ]"说明n是以传值的方式传到lamda体中,传值和传引用的差别请自行百度。捕获列表可按如下规则传入
- [ ] ——什么也没有捕获
- 值捕获:[ a ] ————按值捕获a
- 引用捕获:[ & ] ——按引用捕获任何用到的外部变量
- 隐式捕获:[ = ] ——按值捕获任何用到的外部变量
下面为混合方式
- [ a, &b ] ————按值捕获a,按引用捕获b
- [ a, & ] ————按值捕获a, 其它的变量按引用捕获
- [ &b, = ] ————按引用捕获b,其它的变量按值捕获
- [ this ] ————按值捕获this指针
注意: 假如我们想修改按值传进来的形参,将会发生错误,因为按值捕获的对象不能被修改,如下代码
int n = 10;
[ n ](int a)
{
n += a; // 报错,提示不允许修改n的值
return n;
};
这时我们需要假如一个mutable,如下
int n = 10;
[ n ](int a) mutable
{
n += a; // 正确
return n;
};
关于返回值类型,可由以下规则推导出来
- 如果body仅包含单一的return语句,那么返回值类型是返回表达式的类型(在此隐式转换之后的类型:右值到左值、数组与指针、函数到指针)
- 否则,返回类型是void
譬如我们上面std::sort()的这个例子,lamda表达式是
[](int a, int b) {return a > b;};
a > b 这个表达式返回的类型是bool,因此这个lamda表达式返回类型是bool。
最后一个例子,我们可以把lamda表达式进行赋值,还是利用std::sort()这个例子。我们可以把cmp函数写成如下
std::function<bool(int, int)> cmp = [](int a, int b) {return a > b;};
//std::function包含在头文件functional中,具体用法请自行百度
这样做的好处是可以多次利用lamda表达式。当然,我们可以指定其返回类型为auto,来让其自行判断。
auto cmp = [](int a, int b) {return a > b;};
整理于:
https://www.cnblogs.com/IamTing/p/4541901.html
https://www.cnblogs.com/zhuyp1015/archive/2012/04/08/2438176.html