C++11之Lambda表达式

it2026-08-23  1

Lambda表达式

C++11的一大特性就是引入了Lambda表达式,并在后续的C++14进行了加强。 利用Lambda表达式,可以方便定义和创建匿名函数。一个Lambda表达式表示一个可调用单元,我们可以将其理解为一个未命名的内联函数。

Lambda语法定义

[capture list] (paramters list) mutable exception-> return type{function body}

其中——

capture list,捕获外部变量列表;paramters 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省略了mutable关键字和exception,声明的是一个const类型的表达式,这种表达式不能修改捕获列表中的值;格式2 省略了返回类型return type,但是编译器可以根据functionbody中的return语句推断出Lambda表达式的返回类型,如果没有return语句,默认为void类型;格式3中省略了参数列表,即无参的Lambda表达式。

举个使用Lambda表达式的例子——

#include<iostream> #include<vector> #include<algorithm> using namespace std; int main(){ vector<int> v{12,52,67,87,34,95,16,48}; //使用格式3的Lambda表达式定义sort排序规则 sort(v.begin(),v.end(), [](int&a,int&b){return a<b;}); for(auto&elem:v){ cout<<elem<<" "; } return 0; }

Lambda捕获外部参数

Lambda表达式可以使用其可见范围内的外部变量,但必须明确声明。主要通过中括号[]来捕获外部变量,比如——

#include<iostream> using namespace std; int main(){ int a = 100; auto f = [a]{cout<<a<<endl;}; f();// f相当于一个无参的函数调用 return 0; }

这种方式有别于传统的函数参数,增加了语言使用的灵活性。 Lambda表达式的外部变量捕获有4种方式:值捕获、引用捕获、隐式捕获和混合捕获。

值捕获

值捕获与函数传参数相似,都是按值传递,外部变量的改变不会影响表达式已捕获变量的值——

#include<iostream> using namespace std; int main(){ int a = 100; auto f = [a]{cout<<a<<endl;}; a = 200;// 此时改变a的值 f();// 依旧输出100,而不是200 return 0; }

需要注意的是,捕获的外部变量是const的,无法修改。 如果需要修改,需添加mutable关键字,括号也不能省略,比如说——

#include<iostream> using namespace std; int main(){ int a = 100; auto f = [a]()mutable{cout<<++a<<endl;}; a = 200;// f(); return 0; }

引用捕获

顾名思义,就是捕获一个外部变量的引用,只需要在捕获的外部变量前面加上一个&即可——

#include<iostream> using namespace std; int main(){ int a = 100; auto f = [&a]{cout<<a<<endl;}; a = 200;// 此时改变a的值 f();// 输出200 a = 300; f();//输出300 return 0; }

隐式捕获

有时候,捕获的变量比较多的情况,一一书写变量名,可能就会很麻烦。 针对这种情况,Lambda提供了一种隐式捕获的方法,让编译器自行推断需要捕获哪些变量。 我们只需要定义捕获的方式是值捕获还是引用捕获,这就是隐式捕获。 具体使用方法,举例如下——

#include<iostream> using namespace std; int main(){ int a = 100; int b = 200; int c = 300; int d = 400; auto f = [=]{ cout<<"a = "<<a<<endl <<"b = "<<b<<endl <<"c = "<<c<<endl <<"d = "<<d <<endl;};// 值捕获 f(); return 0; }

只需要把=改成&,就变成引用捕获了,在此不再举例。

混合方式

Lambda还支持以上几种方式的混合使用,具体语法,总结如下——

序号语法作用1[]不捕获任何外部变量2[args …]默认是值捕获的方式,如果需要引用捕获,需要单独在变量名前加&3[this]以值捕获的形式捕获this指针4[=]以值捕获的形式捕获所有外部变量5[&]以引用捕获的方式捕获所有的外部变量6[=,&x]变量x以引用捕获,其余值捕获7[&,x]变量x值捕获,其余引用捕获

Lambda参数列表

Lambda表达式的参数列表和函数的参数列表类似,但是又有所不同,具体表现为——

不支持默认参数列表不支持可变参数列表所有参数必须有参数名

相同之处在于,Lambda表达式的参数列表同样可以作为局部变量看待,能够覆盖同名的全局变量。

参考链接

https://www.cnblogs.com/DswCnblog/p/5629165.html
最新回复(0)