• C++学习之路-Lambda表达式


    Lambda表达式结构

    本质是函数

    完整结构:

    [capture list](params list) mutable exception ->return type{
    			function body
    };
    
    • 1
    • 2
    • 3

    其中,各个内容的含义:

    • capture list:捕获列表,捕获表达式外部的变量,相当于函数传参一样
    • params list:参数列表,该表达式可接收的参数,可省略(当表达式不需要外部传参的时候)
    • mutable:用来指定表达式可以修改捕获变量的值,需要时才添加
    • exception:异常设定
    • return type:表达式的返回类型,相当于函数的返回值类型一样(可省略,当表达式内部不返回任何值的时候)
    • function body:跟函数体一样,也就是函数实现

    但是表达式,需要一个返回值指向这个表达式,也就是函数指针。通常我们采用auto直接指向,省事。

    auto func_ptr = [capture list](params list) mutable exception ->return type{
    			function body
    };
    
    • 1
    • 2
    • 3

    然后,我们调用这个表达式的时候,就像函数一样:需要传入参数列表

    retun type value = func_ptr(params list)
    
    • 1

    比如,举一个简单的例子:

    int a = 10;
    int b = 20;
    
    auto Lambda = [a,b](int para1,int para2)mutable->int {
    	a = a + para1;
    	b = b + para2;
    	return a + b;
    };
    cout << Lambda(1, 1) << endl; //32
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    mutable去掉,在表达式内部就不可以修改a或b的值。如果我在函数内部并没有修改a的值,那么mutable就可以省略,如果有修改捕获值的需求,那就得需要加上mutable。

    在这里插入图片描述

    如果真的想修改a或者b的值,且不想用mutable,那就得采用引用传递了。

    auto Lambda = [&a,&b](int s,int v)->int {
    	a = a + s;
    	b = b + v;
    	return a + b;
    };
    
    //不用auto的话,就得这么写,交代函数指针的类型
    //int (*Lambda)(int,int) 这叫指向函数的指针,必须说明参数列表
    int (*Lambda)(int,int) = [&a,&b](int s,int v)->int {
    	a = a + s;
    	b = b + v;
    	return a + b;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    因为,表达式中的捕获列表默认采用的值传递,也就是说不加引用不加mutable,是直接将a的值传递进来,不会影响外部a的值。

    比如,我将a,b的值传入表达式,然后返回a+b,因为是值传递,所以返回的直接是10+20,而不是a+b本身。所以,即使我后来更改了a和b的值,对结果依然不会有影响

    int a = 10;
    int b = 20;
    
    auto Lambda = [a,b]()->int {
    	return a + b;
    };
    
    a = 20;
    b = 30;
    
    cout << Lambda() << endl; //30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    外部变量捕获 [capture list]

    重点记录一下外部捕获变量的规则

    值捕获

    表达式默认的捕获是值捕获,即只捕获变量的值,不会改变其本身

    int a = 10;
    int b = 20;
    auto Lambda = [a,b]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//10,20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    引用捕获

    当我引用捕获a时,在调用表达式之前,改变a,表达式里面的a也会改变

    int a = 10;
    int b = 20;
    auto Lambda = [&a,b]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//20,20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    隐式捕获(默认全部值捕获)

    只需在捕获列表里传入‘=’,就会默认全部都是值捕获(表达式内部用到的值)

    int a = 10;
    int b = 20;
    int c = 30;
    auto Lambda = [=]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//10,20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    隐式捕获(默认全部引用捕获)

    默认,表达式内部的变量全部是外部变量的引用,因此,外部更改了变量,里面也会更改。

    int a = 10;
    int b = 20;
    auto Lambda = [&]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//20,30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    指定某一个变量是值捕获,其余全是引用捕获

    除了a之外的所有出现在表达式内部的变量,都是引用捕获。

    int a = 10;
    int b = 20;
    
    auto Lambda = [&,a]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//10,30
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    指定某一个变量是引用捕获,其余全是值捕获

    与上面的同理

    int a = 10;
    int b = 20;
    
    auto Lambda = [=,&a]{
    	cout << a << endl;
    	cout << b << endl;
    };
    a = 20;
    b = 30;
    Lambda();//20,20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    Leetcode6254-划分技能点相等的团队
    JS工具类
    树莓集团的全球化征程:数字媒体产业的本土与国际布局
    【打卡】【Linux 设备管理机制】21天学习挑战赛—RK3399平台开发入门到精通-Day18
    JVM调优前置知识-深堆Retained Heap和浅堆Shallow Heap
    poj1521
    Spring扩展接口(4):InstantiationAwareBeanPostProcessor
    python find函数
    CSS中如何实现文字跑马灯效果?
    【数据结构】堆的实现
  • 原文地址:https://blog.csdn.net/weixin_45452278/article/details/126592749