Lambda函数

Lambda函数,亦称为Lambda表达式、匿名函数等,是一种函数对象,Lambda函数可以让函数像普通变量一样进行赋值、传递、函数返回等操作。C++中的Lambda函数经常用来解决如下问题:

  1. 使得程序更加简洁,尤其对于一次性使用的函数。
  2. 有些库函数要求传递的参数是一个函数,但是你又不想写一个函数出来
  3. 使得函数可以自由流动,就像变量一样,这给函数式编程模式奠定了语法基础。

语义规定:

点击查看代码
/**********************************************************
*[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.最后面的()表示调用(执行)该表达式
***************************************************************/
请注意,最右边的圆括号 () 是对Lambda函数调用的符号,不是Lamdba函数本身,我们可以将此 Lambda 函数当做一个对象,赋值给另一个具名的函数对象,再去调用它来更清楚地看到Lambda函数 的本体。

上述例子捕获的 a 和 b 都是只读的,在Lambda函数内部不可修改,但如果有需要修改这些外部参
数,则需要将捕获列表改为引用模式:

点击查看代码
[&a, b]()->int{a=100; return a+b;}();
如果作用域内的变量较多,一个个填写到Lambda外部参数列表显然比较麻烦,此时可以用如下代 码来一次性全部导入:
点击查看代码
// 以传值模式(只读)捕获所有外部变量 
[=]()->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; 
}

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

posted @ 2025-08-29 18:10  Lè_Sage  阅读(25)  评论(0)    收藏  举报