Lambda函数
Lambda函数,亦称为Lambda表达式、匿名函数等,是一种函数对象,Lambda函数可以让函数像普通变量一样进行赋值、传递、函数返回等操作。C++中的Lambda函数经常用来解决如下问题:
- 使得程序更加简洁,尤其对于一次性使用的函数。
- 有些库函数要求传递的参数是一个函数,但是你又不想写一个函数出来
- 使得函数可以自由流动,就像变量一样,这给函数式编程模式奠定了语法基础。
语义规定:
点击查看代码
/**********************************************************
*[capture list](params list)mutable exception → return type{functionbody}
*captruelist: 外部变量列表
*params list: 形参列表
*mutable: 是否可以修改外部变量。
* 默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。
* 在使用mutable时,形参列表不可省略
*exception: 异常设定
*return type: 返回类型
*可以不需要声明返回值,此时返回类型相当于使用decltyp根据返回值推断得到
*function body: 函数体
*************************************************************/
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int a = 1;
int b = 2;
int sum = [a, b]()->int{return a+b;}();
cout << "sum: " << sum << endl;
return 0;
}
/************************************************************
*1.Lambda函数是:[a,b]()->int{return a+b;}
*2.a和b是从外部可见作用域中捕获的变量,默认它们在Lambda函数内部是只读的。
*3.()圆括号内是Lambda函数的形参列表,此处为空,但不可省略。
* 3.1Lambda函数的形参列表一般用于跟容器类结合的时候。
*4.->int 是Lambda函数的返回值类型,可以省略。
*5.{}内部就是Lambda函数的具体代码实现。
*6.最后面的()表示调用(执行)该表达式
***************************************************************/
上述例子捕获的 a 和 b 都是只读的,在Lambda函数内部不可修改,但如果有需要修改这些外部参
数,则需要将捕获列表改为引用模式:
点击查看代码
[&a, b]()->int{a=100; return a+b;}();
点击查看代码
// 以传值模式(只读)捕获所有外部变量
[=]()->int{...};
// 以引用模式(读写)捕获所有外部变量
[&]()->int{...};
点击查看代码
#include <iostream>
// 假设这是一个第三方提供的排序函数,
// 我们无法修改它,但是我们可以通过传递不同的比较函数来改变排序的行为
// (升序或降序又或者通过其他关键字进行排序)
// 以下为C语言的思想 通过函数指针来提供比较的函数
bool MySort( auto x , auto y , bool (*cmp)(int , int))
{
if(cmp(x ,y ))
{
swap(...) ;
}
return true ;
}
bool Cmp(auto x , auto y )
{
return x < y;
}
// 假设这是一个第三方提供的排序函数,
// 我们无法修改它,但是我们可以通过传递不同的比较函数来改变排序的行为
// (升序或降序又或者通过其他关键字进行排序)
// C++思想,使用Lambda表达式实现比较函数的传递
bool MySort1( auto x , auto y , auto cmp)
{
// 通过 cmp 调用Lambda表达式
if(cmp(x, y ))
{
// ......
}
return true;
}
int main(int argc, char const *argv[])
{
// if( MySort(123 , 567 , Cmp ))
// 把如何比较大小的操作函数设计为Lambda表达式并作为参数传递到MySort1函数中
if( MySort1(123 , 567 , [](auto x , auto y){ return x < y;} ))
{
std::cout << "返回真" << std::endl;
}
else {
std::cout << "返回假" << std::endl;
}
return 0;
}
点击查看代码
//那么,Lambda函数形参列表的典型场景是怎样的呢?这里可以举STL算法库中的最简单的一例加
以说明
#include <array>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[])
{
// 定义一个静态数组arr(这是一种STL容器,简单理解为一维数组即可)
array<int, 5> arr = {1,2,3,4,5};
// 使用算法库函数 count_if() 计算 arr 中的偶数数目
int num = count_if(arr.begin(), arr.end(), [](int m){return m%2==0;});
cout << "偶数数目是: " << num << endl;
return 0;
}

这样一来就很清楚了,我们利用Lambda匿名函数逐个接收count_if传递过来的参数(即int m,因为容器arr中的元素类型都是int型整数),并判断其是否为偶数,以期达到计算容器中偶数数目的最终目 的。
当然,算法库的函数所能接收的函数符(functor)不一定是Lambda匿名函数,Lambda匿名函数只是函数符的其中一种形式,它们还可以是普通的函数指针,还有更常见的类函数对象
Lambda匿名函数被设计为一种对象,这意味着可以将它们作为函数的参数、返回值,有时,那些
使用了Lambda函数作为参数、返回值的函数,被称为高阶函数。
浙公网安备 33010602011771号