首页 > 其他分享 >Lambda表达式

Lambda表达式

时间:2023-04-18 20:12:50浏览次数:32  
标签:函数 int 传递 函数指针 表达式 Lambda

Lambda表达式

Lambda 表达式(Lambda Expression)是 C++11 引入的一个“语法糖”,可以方便快捷地创建一个“函数对象”。

从 C++11 开始,C++ 有三种方式可以创建/传递一个可以被调用的对象:

  • 函数指针
  • 仿函数(Functor)
  • Lambda 表达式

函数指针

函数指针是从 C 语言老祖宗继承下来的东西,比较原始,功能也比较弱:

1、无法直接捕获当前的一些状态,所有外部状态只能通过参数传递(不考虑在函数内部使用 static 变量)。
2、使用函数指针的调用无法 inline(编译期无法确定这个指针会被赋上什么值)。

// 一个指向有两个整型参数,返回值为整型参数的函数指针类型
int (*)(int, int);

// 通常我们用 typedef 来定义函数指针类型的别名方便使用
typedef int (*Plus)(int, int);

// 从 C++11 开始,更推荐使用 using 来定义别名
using Plus = int (*)(int, int);

仿函数

仿函数其实就是让一个类(class/struct)的对象的使用看上去像一个函数,具体实现就是在类中实现 operator()比如:

class Plus {
 public:
  int operator()(int a, int b) {
    return a + b;
  }   
};

Plus plus; 
std::cout << plus(11, 22) << std::endl;   // 输出 33

相比函数指针,仿函数对象可通过成员变量来捕获/传递一些状态。缺点就是,写起来很麻烦

Lambda 表达式

Lambda 表达式在表达能力上和仿函数是等价的。编译器一般也是通过自动生成类似仿函数的代码来实现 Lambda 表达式的。上面的例子,用 Lambda 改写如下:

auto Plus = [](int a, int b) { return a + b; };

一个完整的 Lambda 表达式的组成如下:

[ capture-list ] ( params ) mutable(optional) -> ret(optional) { body } 
  • capture-list:捕获列表。前面的例子 auto Plus = [](int a, int b) { return a + b; }; 没有捕获任何变量
  • params:和普通函数一样的参数
  • mutable:只有这个 Lambda 表达式是 mutable 的才允许修改按值捕获的参数,不过修改的仍然是拷贝过来的值,不改变值的本体
  • ret:返回值类型,可以省略,让编译器通过 return 语句自动推导
  • body:函数的具体逻辑

Lambda表达式捕获列表(不建议直接使用 [&] 或 [=] 捕获所有参数):

  • [=] 函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)
  • [&] 函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)
  • [this] 函数体内可以使用Lambda所在类中的成员变量
  • [a] 将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符
  • [&a] 将a按引用进行传递
  • [=,&a, &b] 除a和b按引用进行传递外,其他参数都按值进行传递
  • [&, a, b] 除a和b按值进行传递外,其他参数都按引用进行传递

一些例子

auto function = [] (int first, int second){
    return first + second;
};
	
function(100, 200);
int index = 1;
int num = 100;
auto function = ([=]{
			std::cout << "index: "<< index << ", " 
                << "num: "<< num << std::endl;
	}
);

function();
#include <iostream>
using namespace std;
 
class Lambda {
public:
    void sayHello() {
        std::cout << "Hello" << std::endl;
    };

    void lambda() {
        auto function = [this]{ 
            this->sayHello(); 
        };

        function();
    }
};
 
int main()
{
    Lambda demo;
    demo.lambda();
}

标签:函数,int,传递,函数指针,表达式,Lambda
From: https://www.cnblogs.com/Bdathe/p/17330898.html

相关文章

  • lambda表达式以及异常
    lambda表达式简化匿名内部类*****前提:​ 函数式接口:只有一个被重写的抽象方法的接口​ @FunctionalInterface强制检测一个接口是否为函数式接口语法:​ ()->{}​ ():重写抽象方法的参数列表​ ->:箭头函数,lambda符号​ {}:重写抽象方法的方法体函数式编程:将函数的实现......
  • Java8新特性2_Lambda表达式
    Lambda表达式为什么要用Lambda表达式Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码,将代码像数据一样传递,这样可以写出更简洁、更灵活的代码,作为一个更紧凑的代码风格,使Java语言表达能力得到了提升实例代码Lambda表达式最先替代的就是匿名内部类,假设......
  • Cron表达式介绍与示例
     1.概念介绍Cron表达式是一个具有时间含义的字符串,字符串以5~6个空格隔开,分为6~7个域,格式为XXXXXXX。其中X是一个域的占位符。最后一个代表年份的域非必须,可省略。单个域有多个取值时,使用半角逗号,隔开取值。每个域可以是确定的取值,也可以是具有逻辑意义的特殊字符......
  • html模板里的表达式不能用小于号
    今天用angular写*ngIf="item.cnt <= 5"这个表达式的时候报错,他将<后面的东西当做html标签来看了,怎么办呢可以用html转义字符来表示小于号<换成下面就可以了*ngIf="item.stockCnt &lt= 5"<<&#60;小于号>>&#62;大于号......
  • Cron表达式
    一、字段释义00/5***?秒分时天(月)月天(周)年份(一般省略)二、符号释义*:表示所有可能的值/:表示数值的增量,简单来说,比如分写上0/5表示从0分开始,每隔5分钟?:仅用在天(月)和天(周),表示不指定值,当其中一个有值时,另外一个需要设为?每一个字段都......
  • P1449 后缀表达式-模拟栈
    题目描述所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。如:3*(5-2)+7 对应的后缀表达式为:3.5.2.-*7.+@。在该式中,@ 为表达式的结束符号。. 为操作数的结束符号......
  • 运算符、表达式和语句
    运算符、表达式和语句关键字--->while、typedef运算符--->=、-、*、/、%、++、--复合语句、自动类型转换、强制类型转换编写带有参数的函数while循环示例代码:#include<stdio.h>#defineADJUST7.31intmain(void){constdoubleSCALE=0.333;dou......
  • 【c#表达式树】最完善的表达式树Expression.Dynamic的玩法
    【c#表达式树】最完善的表达式树Expression.Dynamic的玩法 引言在我第一次写博客的时候,写的第一篇文章,就是关于表达式树的,链接:https://www.cnblogs.com/1996-Chinese-Chen/p/14987967.html,其中,当时一直没有研究Expression.Dynamic的使用方法(因为网上找不到资料),就......
  • JavaScript运算符与表达式
    目录一、===二、||三、??与?.???.四、...五、[]{}[]{}一、===严格相等运算符,用作逻辑判断1==1 //返回true1=='1' //返回true,会先将右侧的字符串转为数字,再做比较1==='1' //返回false,类型不等,直接返回falsetypeof查看某个值的类型typeof1 //返回'number'ty......
  • JavaScript 邮箱 验证正则表达式 ,包看懂
    \w就是[0-9a-zA-Z_]\s是[\t\v\n\r\f]\S是[^\t\v\n\r\f]\W是[^0-9a-zA-Z_]\D就是[^0-9]\d就是[0-9].就是[^\n\r\u2028\u2029]。表示几乎任意字符。varreg=/\w{1,30}(\.\w{1,10}){0,2}@\w{1,10}\.\w{1,10}/g\w{1,30}理解为至少有一个字符,最多30个.\w{1,30}理......