C++ lambda表达式

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

目录

一、Lambda表达式概述

1.介绍

2.作用

1)lambda表达式做回调

2.做并行计算

二、Lambda表达式语义分析

1.基本语法分析

2.捕获列表

3.匿名函数简写

三、使用注意


一、Lambda表达式概述

1.介绍

        Lambda表达式是C++11标准引入的一种特性,它提供了一种方便的方式来定义匿名函数。Lambda表达式是一种能够捕捉外部变量并使用它们的函数对象。由捕获列表、参数列表、返回类型和函数体组成;其中,参数列表和返回类型可以忽略,但不可以忽略捕获列表和函数体。

[捕获列表](参数列表) -> 返回类型 {函数体}

        例如:auto f = []{ return 1 + 2; };   或者  auto f = [](int x, int y)->int{ return x + y; };

      (在后面章节会详细介绍使用规则.)

2.作用

        在c++11中提出lambda特性,通过引入lambda表达式,C++11使得编写匿名函数变得更加简洁和方便,提高了代码的可读性和灵活性。其主要作用包括:简化代码、作为算法的参数、回调、并行计算等。以下举几个简单示例:

1)lambda表达式做回调

#include <iostream>
#include <functional>
#include <vector>
#include <unistd.h>

using namespace std;

class EventHandle
{
public:
        void registerCallback(function<void()> callback)
        {
            callbacks.push_back(callback);
        }
        void triggerEvent()
        {
            for(auto &testCallback: callbacks)
            {
                testCallback();
            }
        }
private:
    vector<function<void()>>  callbacks; 
};

int main()
{
    EventHandle eventHandle;
    eventHandle.registerCallback([]{cout<<"run"<<endl;});

    sleep(3);
    eventHandle.triggerEvent(); //触发

    return 0;
}

        在main函数中,我们使用lambda表达式注册了一个回调函数,当事件被触发时,lambda表达式中的代码将执行,输出"run!"。这样,我们可以方便地在事件处理中使用lambda表达式,而不需要显式地定义独立的函数或类来处理回调

2)做并行计算

#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    std::for_each(std::execution::par, numbers.begin(), numbers.end(), [](int& num) {
        num *= 2;
    });

    std::cout << "Result:";
    for (const auto& num : numbers) {
        std::cout << " " << num;
    }
    std::cout << std::endl;

    return 0;
}

         lambda表达式中的操作是将两个数字相加,它接收两个参数(当前的累加结果和下一个元素),并返回它们的和。通过使用并行算法和lambda表达式,我们可以充分发挥多核处理器的能力,提高计算效率。

二、Lambda表达式语义分析

1.基本语法分析

[捕获列表](参数列表) -> 返回类型 {函数体}

auto Add = [](int a, int b) -> int {
        return a + b;
    };

 上述代码表示[ ]传参列表为空,参数为int a和int b,返回值类型为int。函数体为return a+b 的一个匿名函数。一般情况下,编译器可以自动推断出lambda表达式的返回类型,所以我们可以不指定返回类型

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

 注意:如果匿名函数表达式内有多个return操作,编译器无法自动推断出返回类型,此时必须指定返回类型

2.捕获列表

        如果需要在匿名函数内部使用外部变量而不想传参,可以用捕获列表来传参。

int c = 12;
int d = 30;
auto Add = [c, d](int a, int b)->int { 
   cout << "d = " << d  << endl;
   return c;};

 如果在匿名函数内部,加入对变量c,d修改的操作; 则无法编译通过。因为上述捕获列表是通过值进行传递,无法进行修改。那么如何进行修改呢?通过传入引用,这样就可以当作左值被用来修改

int c = 12;
int d = 30;
auto Add = [&c, &d](int a, int b)->int { 
   d = 11;
   cout << "d = " << d  << endl;
   return c;};

以下是捕获列表分类:

[]空捕获列表,Lambda不能使用所在函数中的变量。
[names]names是一个逗号分隔的名字列表,这些名字都是Lambda所在函数的局部
变量。默认情况下,这些变量会被拷贝,然后按值传递,名字前面如果使用
了&,则按引用传递
[&]隐式捕获列表,Lambda体内使用的局部变量都按引用方式传递
[=]隐式捕获列表,Lanbda体内使用的局部变量都按值传递
[&,identifier_list]identifier_list是一个逗号分隔的列表,包含0个或多个来自所在函数的变量,
这些变量采用值捕获的方式,其他变量则被隐式捕获,采用引用方式传递,
identifier_list中的名字前面不能使用&。
[=,identifier_list]identifier_list中的变量采用引用方式捕获,而被隐式捕获的变量都采用按值
传递的方式捕获。identifier_list中的名字不能包含this,且这些名字面前必须
使用&

3.匿名函数简写

        匿名函数由捕获列表、参数列表、返回类型和函数体组成;可以忽略参数列表和返回类型,但不可以忽略捕获列表和函数体,如:auto num = []{ return 1 + 2; };

三、使用注意

  • 匿名函数构建的时候对于按值传递的捕获列表,会立即将当前可以取到的值拷贝一份作为常数(相当于一个右值),然后将该常数作为参数传递
  • 可变性(mutability):默认情况下,lambda表达式不能修改捕获的按值变量。如果需要修改,可以使用mutable关键字修饰lambda表达式。
  • 如果匿名函数表达式内有多个return操作,编译器无法自动推断出返回类型,此时必须指定返回类型
  • 生命周期问题:当lambda表达式捕获了外部变量时,需要注意外部变量的生命周期,以避免悬垂引用(dangling references)或访问已销毁的对象。

关于第四点,请看示例:

int main() {
    int* danglingPtr = nullptr;

    {
        int *p = new int(2);
        auto lambda = [&]() {
            danglingPtr = p; // 捕获局部变量 p 的地址
        };
        lambda();
        delete p;
    } // 离开作用域,p 被销毁

    // 此时 danglingPtr 包含了一个悬垂的指针,访问它是未定义行为
    std::cout << *danglingPtr << std::endl; // 可能导致崩溃或不可预测的行为

    return 0;
}

C++ 中的 Lambda C++11引入了lambda表达式,使得C++程序员能够编写更简洁的回调函数和闭包,表达式用于定义并创建匿名的函数对象,以简化编程工作。 阅读详情

相关推荐

C++lambda表达式

本篇文章我们要学习的是lambda表达式,它是C++11新增的一种特别方便的语法,相较于之前的函数指针以及仿函数都方便了不少,下面就让我们一起来学习吧。

malloc不出对象的博客 2596

一文读懂C++中的Lambda函数:简洁、高效、灵活

一、匿名函数的基本语法; 二、捕获列表: 2.1、值捕获, 2.2、引用捕获, 2.3、隐式捕获, 2.4、空捕获列表, 2.5、表达式捕获, 2.6、泛型 Lambda, 2.7、可变lambda, 2.8、混合捕获, 2.10、Lambda捕获列表总结。 lambda表达式的目的是把函数写的更加内聚;只需要在内部使用,就没必要写到外部,干扰其他函数,同时使代码更简洁。 如果捕获列表为[&],则表示所有的外部变量都按引用传递给lambda使用。

Lion_Long的博客 1万+

C++ Lambda表达式

C++ Lambda表达式C++11引入的匿名函数特性,允许内联定义小型函数。其基本语法包含捕获列表、参数列表、返回类型和函数体。捕获列表支持按值或引用访问外部变量。示例展示了Lambda的多种用法:作为加法函数、匿名比较函数以及与捕获机制结合使用。文章还对比了Lambda函数与内联函数的区别,指出Lambda的优势在于匿名性和变量捕获能力,而内联函数侧重性能优化。Lambda适用于一次性场景如回调函数,使代码更简洁直接。

weixin_54859557的博客 752

C ++ Lambda表达式详解

C ++ Lambda表达式详解 1.Lambda表达式概述 ​ Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 ,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。本文主要介绍Lambda的工作原理以及使用方法。 2.Lambda表达式定义 2.1 Lambda表达式示例 ​

白云之道 6万+

C++11:lambda表达式

lambda表达式就是定义了一个可调用的匿名函数,一般在局部。1.格式mutable捕捉列表 参数去const(单词意思易变的)返回值 函数体};2. lambda表达式各部分说明,该列表总是出现在lambda函数的开始位置,,。捕捉的参数都是自带const的,想要去掉const属性可以用mutable,但是捕捉的对象(变量)仍是一份拷贝,外部的a,b无法被修改,所以mutable 很少用,意义不大,不如用 [&]引用捕捉 ( )引用传参。

zhang_si_hang的博客 1万+

Cpp || lambda 表达式

lambda表达式的使用注意方式

Template Code 2580

C++Lambda表达式

Lambda表达式C++11引入的匿名函数对象,具有以下特点: · 就地定义,无需单独命名 · 可捕获上下文变量 · 自动推导返回类型(多数情况) · 可作为函数参数传递

AAADiao的博客 1万+

C++C++11——lambda表达式

C++11——Lambda表达式

weixin_60478154的博客 4533

C++ 11 Lambda表达式

原文地址:https://www.cnblogs.com/DswCnblog/p/5629165.html C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多高级语言在很早以前就已经提供了Lambda表达式的功能,如C#,Python等。今天,我们就...

键盘上狂欢 5216

C++lambda 表达式

如果同学们学过其他编程语言(如:Java、python),对 lambda 表达式应该不陌生。lambda 表达式最大的作用就是把一个简单的 类/函数 变为一条语句,可以减少代码量,对程序员友好。本文将对 C++lambda 表达式的语法进行学习,并简单理解 lambda 表达式的底层。

在这个博客里,我会分享我的技术见解、项目经验和学习笔记,感谢各位支持~ 1040

C++Lambda表达式的使用

闭包是指一个函数对象,它包含了函数定义时的环境信息,包括捕获的外部变量。闭包的存在使得lambda函数可以延长外部变量的生命周期,并且可以在函数调用结束后仍然访问这些变量。闭包是一个函数对象,它可以捕获外部作用域中的变量,并在其生命周期内访问和修改这些变量。比如:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量 [&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量。函数对象可以像普通的函数一样被调用,其执行的代码就是lambda表达式中的代码。

AkieMo的博客 2633

c++Lambda表达式

摘要:本文深入解析C++ Lambda表达式优化技巧。关键点包括:1)捕获方式选择,建议明确指定捕获变量而非全捕获;2)值捕获与引用捕获的适用场景及陷阱;3)mutable关键字的作用机制;4)C++14初始化捕获和C++20模板Lambda等新特性。文章指出Lambda实质是编译器生成的匿名类实例,并详细分析生命周期管理、避免悬空引用等常见问题。优化建议包含优先值捕获简单类型、对大型对象使用引用/智能指针、标记const捕获等,强调合理使用Lambda能提升代码性能与可读性。

2401_88413914的博客 999

C++11 Lambda表达式

Lambda表达式 C++11的一大特性就是引入了Lambda表达式,并在后续的C++14进行了加强。利用Lambda表达式,可以方便定义和创建匿名函数,一个Lambda表达式表示一个可调用单元,我们可以将其理解为一个未命名的内联函数。 Lambda语法定义 [capture list] (paramters list) mutable exception-&amp;amp;gt; return type{fun...

大山喵写博客的地方 2348

cpp lambda表达式

cpp的lambda函数 形如 [](para1,para2){} [&]()->int{}的函数,常用于sort的cmp等

ZnS_oscar的博客 356

C++11】lambda表达式

C++11之lambda表达式

weixin_63449996的博客 1408

c++ Lambda 表达式

c++ Lambda 表达式

xie__jin__cheng的博客 1186

C++Lambda表达式

今天写LeetCode题的时候看到了别的大佬在排序的时候用到了Lambda表达式,但自己对此还是一知半解,所以在这里介绍下。 1. 概述 C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。 Lambda 的语法形式如下: [函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体} 可以看到,Lambda 主要分为五个部分:[函数对象参数]、(操作符重载函数参数)、mutable 或 exception 声明

Geek_的博客 3649
上一篇: C++引用与移动语义
下一篇: C++11常用关键字
冷瑾瑜
博客等级 码龄7年 267粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值