#include<iostream>
using namespace std;
 
int main()
{
    int a = 1;
    int b = 2;
 
    auto func = [=, &b](int c)->int {return b += a + c;};
    return 0;
}

[capture](parameters) mutable ->return-type{statement}

1.[capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;

2.(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;

3.mutable:mutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空);

4.->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;

5.{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据。具体地,捕捉列表描述了上下文中哪些数据可以被Lambda使用,以及使用方式(以值传递的方式或引用传递的方式)。语法上,在“[]”包括起来的是捕捉列表,捕捉列表由多个捕捉项组成,并以逗号分隔。捕捉列表有以下几种形式:

1.[var]表示值传递方式捕捉变量var;
2.[=]表示值传递方式捕捉所有父作用域的变量(包括this);
3.[&var]表示引用传递捕捉变量var;
4.[&]表示引用传递方式捕捉所有父作用域的变量(包括this);
5.[this]表示值传递方式捕捉当前的this指针。

上面提到了一个父作用域,也就是包含Lambda函数的语句块,说通俗点就是包含Lambda的“{}”代码块。上面的捕捉列表还可以进行组合,例如:

1.[=,&a,&b]表示以引用传递的方式捕捉变量a和b,以值传递方式捕捉其它所有变量;
2.[&,a,this]表示以值传递的方式捕捉变量a和this,引用传递方式捕捉其它所有变量。

不过值得注意的是,捕捉列表不允许变量重复传递。下面一些例子就是典型的重复,会导致编译时期的错误。例如:

3.[=,a]这里已经以值传递方式捕捉了所有变量,但是重复捕捉a了,会报错的;
4.[&,&this]这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复。

Lambda的使用

对于Lambda的使用,说实话,我没有什么多说的,个人理解,在没有Lambda之前的C++ , 我们也是那样好好的使用,并没有对缺少Lambda的C++有什么抱怨,而现在有了Lambda表达式,只是更多的方便了我们去写代码。不知道大家是否记得C++ STL库中的仿函数对象,仿函数想对于普通函数来说,仿函数可以拥有初始化状态,而这些初始化状态是在声明仿函数对象时,通过参数指定的,一般都是保存在仿函数对象的私有变量中;在C++中,对于要求具有状态的函数,我们一般都是使用仿函数来实现,比如以下代码:

/*

#include<iostream>
using namespace std;
 
typedef enum
{
    add = 0,
    sub,
    mul,
    divi
}type;
 
class Calc
{
    public:
        Calc(int x, int y):m_x(x), m_y(y){}
 
        int operator()(type i)
        {
            switch (i)
            {
                case add:
                    return m_x + m_y;
                case sub:
                    return m_x - m_y;
                case mul:
                    return m_x * m_y;
                case divi:
                    return m_x / m_y;
            }
        }
 
    private:
        int m_x;
        int m_y;
};
 
int main()
{
    Calc addObj(10, 20);
    cout<<addObj(add)<<endl; //
发现C++11中,enum类型的使用也变了,更“强”了                                                                                                                                             

    return 0;
}

*/

/*

#include<iostream>
using namespace std;
     
typedef enum
{    
    add = 0,
    sub,
    mul,
    divi
}type;
     
int main()
{    
    int a = 10;
    int b = 20;
     
    auto func = [=](type i)->int {
        switch (i)
        {
            case add:
                return a + b;
            case sub:
                return a - b;
            case mul:
                return a * b;
            case divi:
                return a / b;
        }
    };
     
    cout<<func(add)<<endl;
}

*/

// from : https://www.jb51.net/article/56147.htm

c++ 兰姆达表达式的更多相关文章

  1. LambdaToSql 发布 兰姆达转换sql

    文档目录索引 查询.函数.分组.排序.分页 添加 Insert into 编辑 Update set 删除 Delete 生成实体 内置常用工具类库  文档完善中... 事务处理 Join 连接查询 ...

  2. C/C++ C++ 11 兰姆达

    { auto layer = Layer::create();    auto event = cocos2d::EventListenerTouchOneByOne::create();    ev ...

  3. C#拉姆达(=>)表达式

    前言: 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(=>)表达式 介绍: "Lambda表达式"是一个匿名函数,是一种高效的类似 ...

  4. 如何用拉姆达表达式(Lambda Expressions) 书写左链接查询

    在C#中,如果要实现两个列表的左链接查询,我们的一般用法就是用的linq表达式就是 List<Pet> pets = }, }, } }; List<Pet2> pets2 = ...

  5. SqlSugar常用查询实例-拉姆达表达式

    SqlSugar支持拉姆达表达式查询,匿名对象参数等,相对还是比较方便好用的. 一.查询列表: //查询列表 SqlSugarClient db = SugarContext.GetInstance( ...

  6. 拉姆达表达式(Lambda Expressions)

    上面两种写法是一样的 ,拉姆达表达式也是一种委托, 但引用的是匿名方法

  7. => 朗姆达表达式带入符号

    => 是朗姆达表达式中的用法,是指向的意思具体就是是把=>左边声明的变量带入到=>右边的表达式或者代码段里.

  8. C# 匿名方法和拉姆达表达式

    有时候,我们需要封装一组数据,只有数据,没有方法,并且只用于当前程序,不需要在项目间重用,这时候,如果是传统的使用类来封装的话,大概会是下面这种样子: internal class SomeData ...

  9. .net 在同步方法中使用拉姆达表达式执行async/await异步操作

    代码如下: static void Main(string[] args) { ((Action)(async () =>{ var data = await HttpHelper.GetOnS ...

随机推荐

  1. pip飞起来了

    这里说下Windows下的修改方法,看了网上很多的教程发现都不行,尝试了好久终于发现了可行的方法. 找到python安装目录下的:\Lib\site-packages\pip\models\index ...

  2. string.format()详解

    java中: 从 Java 5.0 开始,String 类新增了一个强大的字符串格式化方法 format().这个方法到现在用的人还是不多,实在是一种浪费.本文带你快速过一遍这个方法的功能,将来你要用 ...

  3. leetcode-第14周双周赛-1273-删除树节点

    题目描述: 自己的提交:动态规划 class Solution: def deleteTreeNodes(self, nodes: int, parent: List[int], value: Lis ...

  4. shell--grep命令+正则表达式+基本语法

    什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 在linux中,通配符是由shell解释的,而正则表达式则 ...

  5. hdu 6085 Rikka with Candies (set计数)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  6. JavaScript 的 API设计原则

    一.接口的流畅性 好的接口是流畅易懂的,他主要体现如下几个方面: 1.简单 操作某个元素的css属性,下面是原生的方法: document.querySelectorAll('#id').style. ...

  7. bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3881 对 S 建 SAM ,每个 T 会让 S 的 parent 树的链并答案+1:在 T ...

  8. djanjo中url路由匹配规则是啥意思

    一,django路由匹配规则的本质是通过正则表达式对用户的url进行匹配. 1,r 是正则表达式中防止转义的符号,例如在python/n代表换行,加上r就不换行了. 2,$ 正则表达式中表示以什么什么 ...

  9. MySQL concat、concat_ws 和 group_concat 的用法

    一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为+----+ ...

  10. MHA+atlas(数据库的高可用与读写分离)

    学习完了mycat的高可用还是复习一下MHA+atlas吧,个人感觉还是比mycat好用,毕竟MHA有数据补全和切换主从的机制 1 MHA是什么? MHA(Master High Availabili ...