• 【C++技能树】Lambda表达式


    在这里插入图片描述
    Halo,这里是Ppeua。平时主要更新C++,数据结构算法,Linux与ROS…感兴趣就关注我bua!


    在这里插入图片描述

    0. Lambda表达式简介

    在C++98及之前,想要对sort进行自定义排序,或者对自定义类型进行排序需要写一个仿函数。

    例如,想要从大到小对num进行排序需要这样写

    struct Greater{
        bool operator()(int x,int y)
        {
            return x>y;
        }
    };
    int main()
    {
        vector<int>num;
        sort(num.begin(),num.end(),Greater());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    为了一个可能只在全局中使用一次的函数来创建一个类得不偿失,也有点麻烦.所以引入了Lambda表达式

    1. Lambda表达式

    在C++11,引入了Lambda表达式来解决这个问题,其更像一种匿名函数.生命周期只在当前这一行

    继续引用上文排序的例子,现在可以这样写

    int main()
    {
        vector<int>num;
        sort(num.begin(),num.end(),[](int x,int y){
            return x>y;
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    仅需要一行即可完成该功能,该函数生命周期也仅在这一行.

    这个表达式长得十分Python,是从Python那引用过来的特性

    2. Lambda表达式语法

    Lamda表达式总体框架

    [capture-list](parameters)mutable ->return-type {
        {statement}
    }
    
    • 1
    • 2
    • 3
    1. statement:为函数体,正常写函数即可

    2. parameters:为参数列表

    3. mutable:可取消参数列表的常量属性

    4. return-type:return-type可由编译器自动推导可省略

    5. capture-list:参数捕获列表,可以理解为接下来可以在函数中使用哪些已有的变量

      • [var]表示复制某一个变量的值
      • [&var]表示引用某一个变量
      • [=]复制所有变量
      • [&]引用所有变量
      • [this]引用this指针

      这些可以进行一个组合,表示复制所有全局变量,仅引用a与b,不可重复引用

      [=,&a,&b](){
          
      }
      重复引用
      [=,a,b](){
          
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      一个引用了全局变量的例子

      int a=0,b=1;
      auto f1=[&,a]()mutable{
      a++,b++;
      };
      f1();
      cout<<a<<" "<<b;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      这里的结果为0,1.加上mutable是为了解决a为const的限制,即可对a进行自增的操作.

    6. Lambda表达式之间不可以互相赋值,即使看起来类型相同,但其背后的类型是不同的.我们用typeid来查看下

      auto f2=[](){cout<<"hello";return 0;};
      auto f1=[](){cout<<"hi";return 0;};
      cout<<"f2: "<<typeid(f2).name()<<endl;
      cout<<"f1: "<<typeid(f1).name();
      
      • 1
      • 2
      • 3
      • 4

    image-20231023192508611

    很明显其为不同的函数类型,所以不可以互相赋值

    1. 其底层为函数对象(仿函数)实现的,本质上没有什么差别

      image-20231023192650565
      image-20230905164632777

  • 相关阅读:
    【C++】string使用&&模拟实现
    【无标题】
    【机器学习】039_合理初始化
    详解 Spark 核心编程之 RDD 序列化
    Flutter开发程序员兼职副业平台推荐
    微信小程序仿苹果负一屏由弱到强的高斯模糊
    深析C语言的灵魂 -- 指针
    开发《羊了个羊》游戏的意义
    靠着这份《Alibaba内部32W字面试手册》我已斩获15份offer
    OpenEuler 部署kubesphere网络配置防火墙规则 开放端口访问 确保基础设施组件可以通过特定端口相互通信
  • 原文地址:https://blog.csdn.net/qq_62839589/article/details/133997067