为什么需要lambda函数
匿名函数是许多编程语言都支持的概念,有函数体,没有函数名。1958年,lisp首先采用匿名函数,匿名函数最常用的是作为回调函数的值。正因为有这样的需求,c++引入了lambda 函数,你可以在你的源码中内联一个lambda函数,这就使得创建快速的,一次性的函数变得简单了。例如,你可以把lambda函数可在参数中传递给std::sort函数
#include <algorithm>
#include <cmath>
void abssort(float* x, unsigned N) {
std::sort(x, x + N,
// Lambda expression begins
[](float a, float b) {
return std::abs(a) < std::abs(b);
});
}
你可能会问,使用函数对象不是也可以吗?是的,函数对象当然没问题,自己写的回调函数,你可以传个函数指针也没有问题。他们有优点也有缺点。函数对象能维护状态,但语法开销大,而函数指针语法开销小,却没法保存范围内的状态。如果你觉得鱼和熊掌不可兼得,那你可错了。lambda函数结合了两者的优点,让你写出优雅简洁的代码。
基本lambda语法
基本形式如下:
[capture](parameters)->return-type {body}
[]叫做捕获说明符,表示一个lambda表达式的开始。接下来是参数列表,即这个匿名的lambda函数的参数,->return-type表示返回类型,如果没有返回类型,则可以省略这部分。想知道为什么返回类型可以这么表示,这涉及到c++11的另一特性,参见自动类型推导,最后就是函数体部分了。
我们可以这样输出"hello,world"
auto func = [] () { cout << "hello,world"; };
func(); // now call the function
变量捕获与lambda闭包实现
string name;
cin >> name;
[&](){cout << name;}();
lambda函数能够捕获lambda函数外的具有自动存储时期的变量。函数体与这些变量的集合合起来叫闭包。
  • [] 不截取任何变量
  • [&} 截取外部作用域中所有变量,并作为引用在函数体中使用
  • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
  • [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
  • [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
  • [x, &y] x按值传递,y按引用传递
  • [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
看到这,不禁要问,这魔法般的变量捕获是怎么实现的呢?原来,lambda是通过创建个小类来实现的。这个类重载了操作符(),一个lambda函数是该类的一个实例。当该类被构造时,周围的变量就传递给构造函数并以成员变量保存起来。看起来跟函数对象很相似。
最后,lambda函数的类型是什么呢,答案是std:function。

C++11 的 lambda 表达式规范如下:

[ capture ] ( params ) mutable exception attribute -> ret { body } (1)  
[ capture ] ( params ) -> ret { body } (2)  
[ capture ] ( params ) { body } (3)  
[ capture ] { body } (4)  

其中

  • (1) 是完整的 lambda 表达式形式,
  • (2) const 类型的 lambda 表达式,该类型的表达式不能改捕获("capture")列表中的值。
  • (3)省略了返回值类型的 lambda 表达式,但是该 lambda 表达式的返回类型可以按照下列规则推演出来:
    • 如果 lambda 代码块中包含了 return 语句,则该 lambda 表达式的返回类型由 return 语句的返回类型确定。
    • 如果没有 return 语句,则类似 void f(...) 函数。
  • 省略了参数列表,类似于无参函数 f()。

mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的 non-const 方法。

exception 说明 lambda 表达式是否抛出异常(noexcept),以及抛出何种异常,类似于void f() throw(X, Y)。

attribute 用来声明属性。

另外,capture 指定了在可见域范围内 lambda 表达式的代码内可见得外部变量的列表,具体解释如下:

  • [a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。
  • [this] 以值的方式捕获 this 指针。
  • [&] 以引用的方式捕获所有的外部自动变量。
  • [=] 以值的方式捕获所有的外部自动变量。
  • [] 不捕获外部的任何变量。

此外,params 指定 lambda 表达式的参数。

转载于:https://www.cnblogs.com/diegodu/p/6142245.html

c++11 lambda相关推荐

  1. C++11:Lambda表达式(匿名函数)理解

    C++在C11标准中引入了匿名函数,即没有名字的临时函数,又称之为lambda表达式.lambda表达式 实质上是创建一个匿名函数/对象.即你可以理解为(Lambda 表达式实际上是一个函数,只是它没 ...

  2. C++11 Lambda表达式(匿名函数)详解

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

  3. C++11 lambda表达式、function类模板、bind函数适配器

    文章目录 lambda表达式 lambda表达式的语法 lambda表达式的原理 function模板 function与重载函数 bind函数适配器 lambda表达式 当我们在写代码的时候如果经常 ...

  4. C++11 Lambda函数(匿名函数)

    C++11引入了lambda表达式,使得程序员可以定义匿名函数,该函数是一次性执行的,既方便了编程,又能防止别人的访问. Lambda表达式的语法通过下图来介绍: Lambda表达式的引入标志,在'[ ...

  5. [C++11]lambda表达式语法

    代码如下: #include <iostream> using namespace std;void func(int x, int y) {int a;int b;[=]() {int ...

  6. C++11 Lambda表达汇总总结

    C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下:               [函数对象参数] (操作符重载函数参数) mutable或ex ...

  7. C++11 Lambda表达式

    1.简介 1.1定义 C++11新增了很多特性,Lambda表达式(Lambda expression)就是其中之一,很多语言都提供了 Lambda 表达式,如 Python,Java ,C#等.本质 ...

  8. C++ 11 Lambda表达式

    C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下:               [函数对象参数] (操作符重载函数参数) mutable或ex ...

  9. C++11::lambda 的用法

    lambda 是个不具名的 function object(或称做 functor),lambda 改变了 C++ 标准库的用法. Lambda 的语法 最小型的 lambda 函数没有参数,如下: ...

最新文章

  1. IT工程师实战英语之一
  2. C++ Const指针学习
  3. HDR视频生态圈追踪
  4. 4.02Day12函数 装饰器
  5. MacOS中运行第一个PySide6实例
  6. autograd手动仿真手记
  7. 基于深度学习的大豆病虫害自动计数(SLIC超像素方法进行图像分割)
  8. Windows10原神二次元美化主题工具包分享
  9. LateX各种命令符号
  10. go开发报 A required privilege is not held by the client 错误
  11. c语言1GB转成B,2018职称计算机考试WPS_Office精选习题9
  12. Vue实现省、市、县三级联动
  13. thzvv.com forum php,为什么Naver账号不能用了?
  14. 简单的购物车和购物车结算
  15. Doc和Docx有什么区别
  16. html空间进入动画界面,HTML5 / CSS3 Transform / Animation 示例页面
  17. 随机画五角星,空心五角星
  18. 求两圆相交面积(模板)
  19. 研发绩效管理和绩效考核_网络绩效伦理
  20. 中科蓝汛蓝牙耳机AB5356A/AB5376A进入CBT模式

热门文章

  1. MyBatis总结五:#{}和${}的用法和区别
  2. python3学习者的福音
  3. Samba服务全攻略
  4. Source Insight(vs2012,ultraedit) 中Tab键设置为4个空格代替
  5. PyRun_SimpleString的无穷怨念
  6. python自动登录百度空间
  7. 斐波那契数列;递归函数;爬楼梯问题;
  8. 前端学习(2939):vue组件的使用
  9. [vue] vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
  10. [vue] 第一次加载页面时会触发哪几个钩子?