博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++11中的Lambda表达式
阅读量:5782 次
发布时间:2019-06-18

本文共 2941 字,大约阅读时间需要 9 分钟。

本文地址:,转载请注明源地址。

“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

ISO C++ 11 标准的一大亮点是引入Lambda表达式。基本语法如下:

[capture list] (parameter list) ->return type { function body } 

其中除了“[ ]”(其中捕获列表可以为空)和“复合语句”(相当于具名函数定义的函数体),其它都是可选的。它的类型是唯一的具有成员operator()的非联合的类类型,称为闭包类型(closure type)。

C++中,一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。

它与普通函数不同的是,lambda必须使用尾置返回来指定返回类型。

例如:调用<algorithm>中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:

bool compare(int &a, int &b){    return a > b;  //降序排序}

然后,再这样调用:

sort(a, a + n, compare);

然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:

sort(a, a + n, [](int a, int b){
return a > b;}); //降序排序

这样一来,代码明显简洁多了。

由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:

auto f = [](int a, int b){
return a > b;});

和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如:

autof = [x](int a, int b){
return a > x;});//x被捕获复制int x = 0,y = 1;auto g = [&](int x){
return ++y;});//y被捕获引用,调用g后会修改y,需要注意y的生存期bool(*fp)(int, int) = [](int a, int b){
return a > b;});//不捕获时才可转换为函数指针

Lambda表达式可以嵌套使用。

即将出版的ISO C++14支持基于类型推断的泛型lambda表达式。上面的排序代码可以这样写:

sort(a, a + n, [](const auto &a, const auto &b){
return a > b;});//降序排序:不依赖a和b的具体类型

因为参数类型和函数模板参数一样可以被推导而无需和具体参数类型耦合,有利于重构代码;和使用auto声明变量的作用类似,它也允许避免书写过于复杂的参数类型。特别地,不需要显式指出参数类型使使用高阶函数变得更加容易。

下面举一个简单使用Lambda表达式的例子:

#include
#include
#include
#include
using namespace std;int main(){ vector
v; for (int i = 0; i < 10; i++){ v.push_back(i); } for_each(v.begin(), v.end(), [](int n){cout << n << " "; }); cout << endl; return 0;}

Lambda表达式默认的返回类型为void

为了对比,下面使用函数对象实现相同功能的代码:

#include
#include
#include
#include
#include
using namespace std;class LambdaFunctor{public: void operator()(int n) const{ cout << n << " "; }};int main(){ vector
v; for (int i = 0; i < 10; i++){ v.push_back(i); } for_each(v.begin(), v.end(), LambdaFunctor()); cout << endl; return 0;}

对比一下,就会发现使用Lambda表达式要简洁得多

上面提到的Lambda表达式可以操作所在作用域的变量,这需要通过被称为“捕获”的特殊语法来实现,就是通过在[]内列出将要捕获的“外部”变量列表,这样在函数体内就可以访问并操作这些变量。参考下面的代码:

#include
#include
#include
#include
#include
using namespace std;int main(){ vector
v; for (int i = 0; i < 10; i++){ v.push_back(i); } //使用for_each语句和Lambda表达式来实现对偶元素的计数 int evenCount = 0; for_each(v.begin(), v.end(), [&evenCount](int n){ cout << n; if (n % 2 == 0) { cout << " is even" << endl; evenCount++; } else { cout << " is odd" << endl; } }); cout << "There are " << evenCount << " even numbers in the vector." << endl; getchar(); return 0;}

参考资料

百度百科

《Visual C++2010权威开发指南》

你可能感兴趣的文章
PostgreSQL并发控制(MVCC, 事务,事务隔离级别)
查看>>
12月19日一周一次【Python基础语法】
查看>>
DM***的第二阶段OSPF
查看>>
python socket编程
查看>>
20180702搭建青岛RAC记录
查看>>
安装部署TIDB分布式数据库
查看>>
Spring Security OAuth 实现OAuth 2.0 授权
查看>>
linux文件及简单命令学习
查看>>
dubbo源码分析-架构
查看>>
新 Terraform 提供商: Oracle OCI, Brightbox, RightScale
查看>>
6套毕业设计PPT模板拯救你的毕业答辩
查看>>
IT兄弟连 JavaWeb教程 JSP与Servlet的联系
查看>>
Windows phone 8 学习笔记
查看>>
linux并发连接数:Linux下高并发socket最大连接数所受的各种限制
查看>>
洛谷——P2176 [USACO14FEB]路障Roadblock
查看>>
详解区块链中EOS的作用。
查看>>
我的友情链接
查看>>
mysql-error 1236
查看>>
sshd_config设置参数笔记
查看>>
循序渐进Docker(一)docker简介、安装及docker image管理
查看>>