使用 STL 时,往往会大量用到函数对象,为此要编写很多函数对象类。有的函数对象类只用来定义了一个对象,而且这个对象也只使用了一次,编写这样的函数对象类就有点浪费。

而且,定义函数对象类的地方和使用函数对象的地方可能相隔较远,看到函数对象,想要查看其 operator() 成员函数到底是做什么的也会比较麻烦。

对于只使用一次的函数对象类,能否直接在使用它的地方定义呢?Lambda 表达式能够解决这个问题。使用 Lambda 表达式可以减少程序中函数对象类的数量,使得程序更加优雅。

Lambda 表达式的定义形式如下:

[外部变量访问方式说明符] (参数表) -> 返回值类型
{语句块
}

其中,“外部变量访问方式说明符”可以是=或&,表示{}中用到的、定义在{}外面的变量在{}中是否允许被改变。=表示不允许,&表示允许。当然,在{}中也可以不使用定义在外面的变量。“-> 返回值类型”可以省略。

下面是一个合法的Lambda表达式:

[=] (int x, int y) -> bool {return x%10 < y%10; }

Lambda 表达式实际上是一个函数,只是它没有名字。下面的程序段使用了上面的 Lambda 表达式:

int a[4] = {11, 2, 33, 4};
sort(a, a+4, [=](int x, int y) -> bool { return x%10 < y%10; } );
for_each(a, a+4, [=](int x) { cout << x << " ";} );

这段程的输出结果是:
11 2 33 4

程序第 2 行使得数组 a 按个位数从小到大排序。具体的原理是:sort 在执行过程中,需要判断两个元素 x、y 的大小时,会以 x、y 作为参数,调用 Lambda 表达式所代表的函数,并根据返回值来判断 x、y 的大小。这样,就不用专门编写一个函数对象类了。

第 3 行,for_each 的第 3 个参数是一个 Lambda 表达式。for_each 执行过程中会依次以每个元素作为参数调用它,因此每个元素都被输出。

下面是用到了外部变量的Lambda表达式的程序:

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{int a[4] = { 1, 2, 3, 4 };int total = 0;for_each(a, a + 4, [&](int & x) { total += x; x *= 2; });cout << total << endl;  //输出 10for_each(a, a + 4, [=](int x) { cout << x << " "; });return 0;
}

程序的输出结果如下:
10
2 4 6 8

第 8 行,[&]表示该 Lambda 表达式中用到的外部变量 total 是传引用的,其值可以在表达式执行过程中被改变(如果使用[=],编译无法通过)。该 Lambda 表达式每次被 for_each 执行时,都将 a 中的一个元素累加到 total 上,然后将该元素加倍。

实际上,“外部变量访问方式说明符”还可以有更加复杂和灵活的用法。例如:

  • [=, &x, &y]表示外部变量 x、y 的值可以被修改,其余外部变量不能被修改;
  • [&, x, y]表示除 x、y 以外的外部变量,值都可以被修改。

例如下面的程序:

#include <iostream>
using namespace std;
int main()
{   int x = 100,y=200,z=300;auto ff  = [=,&y,&z](int n) {cout <<x << endl;y++; z++;return n*n;};cout << ff(15) << endl;cout << y << "," << z << endl;
}

程序的输出结果如下:
100
225
201, 301

第 6 行定义了一个变量 ff,ff 的类型是 auto,表示由编译器自动判断其类型(这也是 C++11 的新特性)。本行将一个 Lambda 表达式赋值给 ff,以后就可以通过 ff 来调用该 Lambda 表达式了。

第 11 行通过 ff,以 15 作为参数 n 调用上面的 Lambda 表达式。该 Lambda 表达式指明,对于外部变量 y、z,可以修改其值;对于其他外部变量,例如 x,不能修改其值。因此在该表达式执行时,可以修改外部变量 y、z 的值,但如果出现试图修改 x 值的语句,就会编译出错。

原文地址:http://c.biancheng.net/view/433.html

C++11 Lambda表达式(匿名函数)详解相关推荐

  1. Java中Lambda表达式使用及详解

    Java中Lambda表达式使用及详解 前言 一.Lambda表达式的简介 Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中.使 ...

  2. 匿名函数python_基于python内置函数与匿名函数详解

    内置函数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() d ...

  3. java的匿名函数_JAVA语言中的匿名函数详解

    本文主要向大家介绍了JAVA语言中的匿名函数详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 一.使用匿名内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: ...

  4. C++11 lambda表达式与函数对象

    C++ lambda表达式与函数对象 lambda表达式是C++11中引入的一项新技术,利用lambda表达式可以编写内嵌的匿名函数,用以替换独立函数或者函数对象,并且使代码更可读.但是从本质上来讲, ...

  5. C# 匿名函数 详解

    文章目录[点击展开](?)[+] 匿名函数的定义和用途 两种匿名函数 C委托的发展 C 10 C 20 C 30 从 C 10 到 C 30委托示例 Unity支持C30的lambda MSDN委托文 ...

  6. python 闭包中的匿名函数详解!

    匿名函数 孔子曰:温故而知新,可以为师矣. 天若有情天亦老,人间正道是沧桑. Python–lambda表达式 lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就 ...

  7. Python中匿名函数详解

      匿名函数是指没有名字的函数,应用在需要一个函数,但是又不想费神去命名这个函数的场合.通常情况下,这样的函数只使用一次.在Python中,使用 lambda 表达式创建匿名函数,其语法格式如下: r ...

  8. MATLAB 匿名函数详解(超级全面)

    匿名函数与之相对的即为需要.m文件存储的命名函数,匿名函数可以在任意地方定义(包含命令行窗口),且由于没有固定的名称,函数是可以像变量一样被传递的.以下详细讲解一下MATLAB中不可或缺的一部分具体能 ...

  9. Javascript进阶:匿名函数详解

    匿名函数:意如其名,就是没有名字的函数. function (arg1,arg2){..... } 匿名函数的普遍用法: 1.赋值给变量: var func=function(arg1,arg2){. ...

  10. python的shutil模块是内置的_Python之shutil模块11个常用函数详解,python内置函数是什么...

    Python之shutil模块11个常用函数详解,python内置函数是什么 shutil 是 Python 中的高级文件操作模块,与os模块形成互补的关系,os主要提供了文件或文件夹的新建.删除.查 ...

最新文章

  1. pandas比较两个dataframe特定数据列的数值是否相同并给出差值:使用np.where函数
  2. 泊松回归(Poisson regression)、COX回归、分类器变回归器、回归算法注意事项、多重共线性问题
  3. Android拖动和缩放图片
  4. javascript常用工具类封装
  5. 台式电脑如何截屏_电脑如何安装安卓系统 台式机装安卓系统教程
  6. java访问类的方法_Java:如何从另一个类访问方法
  7. 负载均衡工具 haproxy 单机安装部署完整流程
  8. linux apache目录权限配置,Linux系统架构-----Apache的用户访问权限的设置
  9. 设备上的介质簇的结构不正确_环保设备选型参考系列——生化系统之潜水搅拌机【价格】...
  10. Linux中设置Git显示颜色
  11. 给大家推荐一本书啊啊~
  12. FortiClient cannot establish caused by TLS version
  13. 小程序cms系统服务器选择,如何三分钟为小程序打造管理后台
  14. SAP 消息号 KE391:在 CO-PA中分配条件类型PR00的问题
  15. Canvas 画直线
  16. python exec函数和eval函数_python中的exec()函数和eval()函数
  17. python语言发展历史
  18. 记账想要简单又安全,使用电脑记账是最佳的选择
  19. iPhone开发网站、论坛、博客 .
  20. 3.2 项目(多肉)

热门文章

  1. 2020数字中国创新大赛—算法赛开源方案复盘笔记
  2. 高清音质背后:网易云信音乐教学方案技术解密
  3. 产品经理和UX设计师,变革已可期
  4. Android adb input 命令介绍
  5. java--Hibernate添加数据save
  6. python之SQLAlchemy ORM
  7. ASP.NET MVC开发,编辑页面和添加页面基本相同,我们控制器 Add Edit是共用同一个View吗?...
  8. windows XP常见进程(个人总结)
  9. git常用操作命令整理大全(含github操作)
  10. go gin 第二次使用ShouldBindJSON失效的原因及解决办法:使用ShouldBindBodyWith代替