什么是Lanmbda?

  简短函数,就地书写。常用于向函数(算法)传递函数参数。

语法

  Lambda 表达式,[capture](paras)mutable->return type{statement} 全部语法格式,分如下章节介绍:

  • [capture]: 捕获列表。捕获列表,总是出现在 lambda 函数的开始处。事实上[ ]是lambda 的引用符。换句话说,编译器根据引出符判断接下来的代码是否是 lamba 函数。
  • (paramers): 参数列表。与普能函数的参数列表一致。如果不需要传递参数,可以连同()一起省略。
  • mutable: 默认情况下,lambda 函数总是一个 const 函数,mutable 可以取消其常量性。在使用该修饰符时,参数列表不可以省略(即使参数为空)。
  • ->return-type: 返回类型。用于追踪返回类型形式声明函数的返回类型。出于方便,不需要返回值的时候可以连同->一起省略。此外返回类型明确的情况下,也可以省略该部分。编译器可以自行推导。
  • {statement}: 函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

格式1——[]{}闭包+函数体

#include <iostream>
using namespace std; int main(int argc, char *argv[])
{
auto foo = []{ return + ;};
cout<<foo();
cout<<[]{ return + ;}()<<endl;
return ;
}

格式2——[](){}闭包+参数+函数体

格式3——[]()->{}闭包+参数+返回值+函数体

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
auto foo = [](int x, int y)->int{return x + y;};
cout<<foo(,)<<endl;
cout<<[](int x, int y){return x + y;}(,)<<endl;
return ;
}

格式4——[]()mutable->{}闭包+参数+可修改+返回值+函数体

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int x = ; int y = ;
cout<<"main:"<<x<<y<<endl;
auto foo = [=]()mutable{
x = ;
y = ;
cout<<"lambda:"<<x<<y<<endl;
};
foo();
cout<<"main:"<<x<<y<<endl;
return
;
}

———————————————模块说明—————————————————

[]闭包

lambda 函数能够捕获 lambda 函数外的具有自动存储时期的变量。函数体与这些变
量的集合合起来叫闭包。闭包的概念在 lambda 中通过[]来体现出来。

  • [] 不截取任何变量。[bar] 仅对外部变量 bar 值传递在函数体中使用。
  • [&bar] 仅对外部变量 bar 引用传递在函数体中使用。
  • [x, &y] 仅 x 按值传递,y 按引用传递在函数体中使用。。
  • [&} 截取外部作用域中所有变量,并作为引用传递在函数体中使用。
  • [=] 截取外部作用域中所有变量,并按值传递在函数体中使用。
  • [=, &foo] 截取外部作用域中所有变量,并值传递在函数体中使用,但是对 foo变量使用引用传递。
  • [&, =foo] 截取外部作用域中所有变量,在函数体中作引用传递使用,但是对foo 变量作值传递。

  上述,中涉及到值传递要发生拷贝行为,而引用传递则不会发生拷贝行为。捕获列表中不允许重复。比如:[=, a] [&,&this]。闭包的本质,初始化 lamda 表达式。

mutable 作用——截取值 还是截取引用?

int main()
{
int i=;
auto f=[i](){return i+=;};
i=;
auto j=f();
cout<<"i="<<i<<endl;
cout<<"j="<<j<<endl; return ;
}

  运行此函数会提示:error: assignment of read-only variable 'i'    auto f=[i](){return i+=5;};
  

  说明{return i+=5;}内的i是受到保护的,无法修改。如果此时将[i](){return i+=5;};改为 [&i](){return i+=5;};就能通过编译,由于传入的是引用,所以i的改变是
  执行结果:
  i=5;
  j=5;

mutable加持!

int main()
{
int i=;
auto f=[i](){return i+=;};
i=;
auto j=f();
cout<<"i="<<i<<endl;
cout<<"j="<<j<<endl;
 
auto f1=[i](){return i+=;};
  cout<<"k="<<k<<endl;
return ;
}

  如果将表达式改为[i]()mutable{return i+=5;};也可以通过,mutable改变了{return i+=5;} i 的const属性,也可以通过编译。

  运行结果:
  i=0;
  j=47;

  K=5;

这说明了什么?
  lambda表达式中[i]值的捕获是发生在编译期的!执行时此时 i=42 值早已拷贝传入。所以 i 之后的改变对于表达式运行并无任何影响。

  也就是说,当声明时lambda表达式对外部变量(i)以赋值的方式捕获后赋给一个“函数指针”,执行该函数指针时,捕获的变量 (i) 不与外部发生任何关系,无论外部变量如何改变。要想重新“刷新”内部变量,需要重新声明该lambda表达式。
  

  mutable参数只对只[]闭包中捕获的(非引用)值才有作用。对于()传入的参数没有任何影响。

C++11之lambda表达式解析的更多相关文章

  1. C++11 lambda 表达式解析

    C++11 新增了很多特性,lambda 表达式是其中之一,如果你想了解的 C++11 完整特性,建议去这里,这里,这里,还有这里看看.本文作为 5 月的最后一篇博客,将介绍 C++11 的 lamb ...

  2. 「C++11」Lambda 表达式

    维基百科上面对于 lambda 的引入是如下描述的: 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find.用户经常希望能够在算法函数调用的附近定义一个临时的述部函数( ...

  3. C++11之lambda表达式

    lambda表达式源于函数式编程的概念,它可以就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象.lambda表达式的类型在C++11中被称为"闭包类型",也可以 ...

  4. SqlHelper简单实现(通过Expression和反射)5.Lambda表达式解析类

    这个ExpressionHelper类,是整个SqlHelper中,最核心的一个类,主要功能就是将Lambda表达式转换为Sql语句.同时这个转换过程比较复杂,所以下面详细讲解一下思路和这个类的作用. ...

  5. C++11 里lambda表达式的学习

    最近看到很多关于C++11的文档,有些是我不怎么用到,所以就略过去了,但是lambda表达式还是比较常用的,其实最开始学习python的时候就觉得lambda这个比较高级,为什么C++这么弱.果然C+ ...

  6. 【C++11】 lambda表达式

    i.e.int x = 10;int y = 20;int z = [&]{ x = x * x; y = y * y; return x + y;}(); 上面z后面以[]开头的为一个lam ...

  7. C++11之lambda表达式应用

    应用 foreach语句中 #include <time.h> #include <algorithm> using namespace std; void func(int ...

  8. c++11:lambda表达式的使用

    lambda表达式的一般形式: [capture list] (parameter list) -> return type{function body}; 其中,capture list (捕 ...

  9. STL - C++ 11的Lambda表达式(上)

    Lambda始自C++ 11,是一种在表达式或语句内指定函数行为的定义式. 你可以定义函数行为作为对象,以inline实参的形式传给算法作为predicate(判断式). eg: std:transf ...

随机推荐

  1. Locality-sensitive hashing Pr[m(Si) = m(Sj )] = E[JSˆ (Si, Sj )] = JS(Si, Sj )

    A hash function that maps names to integers from 0 to 15. There is a collision between keys "Jo ...

  2. Linux系统中的python2.x升级至python3

    python2.x升级至python3 由于需要在公司测试环境搭建的Jenkins上面运行接口自动化脚本,所以需要对Jenkins所处的服务器的python环境进行升级,以便运行python3编写的脚 ...

  3. quick-cocos2d-x教程11:实现http通信,并与站点php对接,可实现登录等常见功能

    手机游戏眼下是弱联网居多,http登录是经常使用功能.我们如今就来实现. 在启动时候.自己主动请求http. function MainScene:ctor()     local url = &qu ...

  4. Pentaho BIServer Community Edtion 6.1 使用教程 第一篇 软件安装

    一.简介: Pentaho BI Server 分为企业版和社区版两个版本.其中 社区版 CE(community edtion) 为免费版本. 二.下载CE版(CentOS): 后台下载命令: no ...

  5. spring-data-redis RedisTemplate操作

    使用RedisTemplate来对对象.String等做缓存处理 首先定义一个对象并重写toString方法 public class UserInfo implements Serializable ...

  6. org.apache.catalina.Lifecycle

    org.apache.catalina.Lifecycle start() *  ----------------------------- *  |                         ...

  7. Java基础教程:HashTable与HashMap比较

    Java基础教程:HashTable与HashMap比较 1.  关于HashMap的一些说法: a)  HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体.HashMap的底层结 ...

  8. 加州小学grade1,学习计划

    Visual vocabulary Grammar Spelling Maths Chapter 1 Patterns and Number SenseChapter 2Understanding A ...

  9. html5+CSS3实现的炫酷超链接特效

    今天为大家介绍一个非常炫酷的超链接特效.在你做一些前端的网页时可以在里面去用上这些前卫时尚的效果. 这些超链接特性,大都是借助伪元素.svg.HTML5动画来实现的.效果都很漂亮,不信看下面. 用你的 ...

  10. 第一节 课程简介与HTML5概述

    第一节 课程简介与HTML5概述 *********************************************************** 1.1课程简介 教学目的: 从基础入手到能够运 ...