【C++11】Lambda表达式使用详解

系列文章目录

C++11新特性使用详解-持续更新


文章目录

    • 系列文章目录
    • 简介
    • 一、特点
    • 二、语法结构
    • 三、实例
      • 1.排序
      • 2.容器赋值
      • 3.传参


简介

Lambda表达式是一种用于创建匿名函数的语法结构。它可以在需要函数对象的地方使用,而无需显式定义一个命名函数。Lambda表达式在C++中最早出现在C++11标准。


一、特点

  • 简洁:Lambda表达式可以快速创建小型函数,无需定义单独的函数或函数对象,使代码更加简洁。
  • 适应性强:Lambda表达式可以方便地捕获外部变量,并对其进行操作,增强了代码的灵活性和可重用性。
  • 匿名性:Lambda表达式是匿名的,可以在代码中直接使用,无需预先定义或命名。

二、语法结构

[capture list](parameters list) -> return_type { function body }

capture list:捕获列表,用于指定lambda表达式中使用的外部变量,不可省略。

[]:表示不捕获任何变量
[var]:表示捕获变量var;还可以是[var1, var2],表示捕获多个变量
[=]:值捕获,捕获外部作用域所有变量,在函数体内有个副本
[&]:引用捕获,捕获值传递外部作用域所有变量,在函数体内当引用使用
[=,&var]:捕获外部作用域所有变量,按引用捕获变量var
[this]:捕获当前类中this变量

parameters list:参数列表,用于指定lambda函数的参数。可省略
return_type:返回类型,指定lambda函数的返回类型。可省略,编译器会自动推断返回类型。
function body:lambda函数的具体实现逻辑,不可省略。


三、实例

1.排序

使用Lambda表达式排序
std::sort 是 C++标准库中的一个算法函数,用于对容器中的一系列值进行排序。第三个参数是一个布尔值,用于指定排序的顺序。它决定了元素是按照升序还是降序进行排序。

如果第三个参数为true,则元素将按照升序进行排序,即从小到大排列。
如果第三个参数为false,则元素将按照降序进行排序,即从大到小排列。

根据C++的排序算法的约定,当lambda函数体(x < y)返回true时,std::sort将把元素x放在元素y的前面。

{//使用Lambda表达式对容器进行排序std::vector<int> vi = { 20,10,6,50 };std::sort(vi.begin(), vi.end(), [](int x, int y) {return x < y; });// 输出排序后的容器内容std::cout << "使用Lambda表达式对int类型容器进行排序" << std::endl;for (auto i : vi){std::cout << i << " ";}std::cout << std::endl;//使用函数来代替lambda表达式对构造体排序std::vector<Person> personVec1 = { Person{"Tom", 10}, {"Jack", 14}, {"Ben", 9}, {"Mike", 7} };std::sort(personVec1.begin(), personVec1.end(), IsYounger);// 输出排序后的容器内容  std::cout << "使用函数对构造体排序" << std::endl;for (auto person : personVec1){std::cout << person.name.c_str() << " " << person.age << std::endl;}//使用重载函数来代替lambda表达式对构造体排序std::vector<Person> personVec2 = { Person{"Tom", 10}, {"Jack", 14}, {"Ben", 9}, {"Mike", 7} };std::sort(personVec2.begin(), personVec2.end(), Person());std::cout << "使用重载函数对构造体排序" << std::endl;for (auto person : personVec2){std::cout << person.name.c_str() << " " << person.age << std::endl;}//使用lambda表达式对构造体排序(常规写法)std::vector<Person> personVec3 = { Person{"Tom", 10}, {"Jack", 14}, {"Ben", 9}, {"Mike", 7} };auto IsYounger = [](Person x, Person y) { return x.age < y.age; };std::sort(personVec3.begin(), personVec3.end(), IsYounger);std::cout << "使用lambda表达式对构造体排序(常规写法)" << std::endl;for (auto person : personVec3){std::cout << person.name.c_str() << " " << person.age << std::endl;}//使用lambda表达式对构造体排序(匿名函数写法)std::vector<Person> personVec4 = { Person{"Tom", 10}, {"Jack", 14}, {"Ben", 9}, {"Mike", 7} };std::sort(personVec4.begin(), personVec4.end(), [](Person x, Person y) {return x.age < y.age;});std::cout << "使用lambda表达式对构造体排序(匿名函数写法)" << std::endl;for (auto person : personVec4){std::cout << person.name.c_str() << " " << person.age << std::endl;}
}

2.容器赋值

使用lambda表达式给容器赋值
std::generate 是 C++ 标准库中的一个算法函数,用于生成一系列值并将其存储在容器中。它接受一个范围(由迭代器指定)和一个生成器函数(可以是函数指针、函数对象或 lambda表达式),并使用生成器函数生成值来填充范围内的元素。

{std::vector<int> tmpVector{ 0,0,0,0,0 };int i = 10;int num = 0;generate(tmpVector.begin(), tmpVector.end(), [i, &num]() {num = i * i + num;return num;});std::cout << "使用lambda表达给tmpVector赋值" << std::endl;std::cout << "打印i和num的值,以查看值传递和引用传递的区别" << std::endl;std::cout << "i=" << i << "  num=" << num << std::endl;    //输出结果:i=10 num=500std::cout << "打印tmpVector中的值----------" << std::endl;for_each(tmpVector.begin(), tmpVector.end(), myPrintf);  // 输出结果:100 200 300 400 500std::cout << std::endl;
}

3.传参

值传递和引用传递形参(和普通函数的值传递和引用传递一样)

{std::vector<int> tmpVector{ 0,1,2,3,4 };int tmpNum1 = 10;int tmpNum2 = 5;std::cout << "lambda表达默认捕获外部变量,形参以值传递方式" << std::endl;for_each(tmpVector.begin(), tmpVector.end(), [=](int x) {x = x * tmpNum1 + tmpNum2;std::cout << "x=" << x << std::endl;  //输出结果:5 15 25 35 45});for_each(tmpVector.begin(), tmpVector.end(), myPrintf);  //输出结果:0 1 2 3 4std::cout << std::endl;std::vector<int> tmpVector1{ 0,1,2,3,4 };std::cout << "lambda表达默认捕获外部变量,形参以引用传递方式" << std::endl;for_each(tmpVector1.begin(), tmpVector1.end(), [=](int &x) {x = x * tmpNum1 + tmpNum2;std::cout << "x=" << x << std::endl;  // 输出结果:5 15 25 35 45});for_each(tmpVector1.begin(), tmpVector1.end(), myPrintf);  //输出结果:5 15 25 35 45std::cout << std::endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/152650.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端学java】Java中的接口和枚举概念(7)

theme: smartblue 往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类…

自定义函数

Spark自定义函数 spark 中的 UDF (UserDefinedFunction) 大家都不会陌生, UDF 其实就是将一个普通的函数, 包装为可以按 “行“ 操作的函数, 用来处理 DataFrame 中指定的 Columns. 例如, 对某一列的所有元素进行 1 操作, 它对应 mapreduce 操作中的 map 操作. 这种操作有的主…

《opencv实用探索·一》QT+opencv实现图片拼接和Mat转QImage

本文利用opencv实现了几个好用的功能&#xff0c;包含两个文件&#xff0c;如下&#xff1a; 源码放在文章末尾 imageProcessing类包含三个功能&#xff1a; 1、图像拼接 cv::Mat imageMosaic(cv::Mat mat1, cv::Mat mat2, MosaicMode mosaicMode);mat1和mat2为两个待拼接的…

Matplotlib实现Label及Title都在下方的最佳姿势

Matplotlib实现Label及Title都在下方的最佳姿势 1. 问题背景2. 基本思想&#xff08;可以不看&#xff09;3. 方法封装4. 调用实例5. 总结6. 起飞 1. 问题背景 用python绘制下面这种图的时候&#xff0c;一般用xlable作为子图的标题&#xff0c;这是因为plt.title()方法绘制的…

人工智能:科技魔法赋予生活新意

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

自学ansible笔记

一、认识ansible Ansible是一款开源自动化运维工具。它有如下特点&#xff1a; 1、不需要安装客户端&#xff0c;通过sshd去通信&#xff0c;比较轻量化&#xff1b; 2、基于模块工作&#xff0c;模块可以由任何语言开发&#xff0c;比较自由和开放&#xff1b; 3、不仅支持命…

WPF显示3D图形

C# 中的 WPF (Windows Presentation Foundation) 支持显示3D图形。WPF 使用 DirectX 作为底层图形引擎&#xff0c;这意味着它可以处理包括3D图形在内的复杂渲染任务。 在 WPF 中&#xff0c;你可以使用一些内置的类和控件来创建和显示3D对象。这包括 Viewport3D, Camera, Mod…

Android studio run 手机或者模拟器安装失败,但是生成了debug.apk

错误信息如下&#xff1a;Error Installation did not succeed. The application could not be installed&#xff1a;List of apks 出现中文乱码&#xff1b; 我首先尝试了打包&#xff0c;能正常安装&#xff0c;再次尝试了debug的安装包&#xff0c;也正常安装&#xff1…

再谈谷歌GMS认证之Android 13

写在前面的话 2023年来到一个新的公司&#xff0c;传说中的做互联网金融即将上市的高大上公司。 入职后才发现就是做pos机设备的一个小厂 哎&#xff0c;什么命啊&#xff01; 工作和手机开发的工作重合度可以达到95%以上&#xff0c;我不想做手机&#xff0c;偏偏又干上…

计算机基础知识54

ORM的介绍 # ORM是什么&#xff1f; 我们在使用Django框架开发web应用的过程中&#xff0c;不可避免地会涉及到数据的管理操作&#xff08;增、删、改、查&#xff09;&#xff0c;而一旦谈到数据的管理操作&#xff0c;就需要用到数据库管理软件&#xff0c;例如mysql、oracle…

Ubuntu20.0中安装Gradle

下载Gradle到temp文件夹 wget https://services.gradle.org/distributions/gradle-8.3-bin.zip -P /tmp 然后解压文件到/opt/gradle目录 sudo unzip -d /opt/gradle /tmp/gradle-8.3.zip 配置Gradle环境变量 接下来我们会创建一个gradle.sh文件来保存Gradle的环境变量 sudo…

ubuntu20.04蓝牙连接airpods

ubuntu20.04蓝牙连接airpods 解禁蓝牙安装blueman设置模式连接上没有声音的问题 解禁蓝牙 sudo rmmod btusb sleep 1 sudo modprobe btusb sudo /etc/init.d/bluetooth restart安装blueman sudo apt install blueman sudo apt-get install pulseaudio-module-bluetooth sudo …

『亚马逊云科技产品测评』活动征文|构建生态农场家禽系统

『亚马逊云科技产品测评』活动征文&#xff5c;构建生态农场家禽系统 授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 前…

VBA如何快速识别Excel单元格中的文本数字

Excel中一种非常特殊的数字&#xff0c;这些数字看似数字&#xff0c;其实是文本格式&#xff08;下文简称为文本数字&#xff09;&#xff0c;在单元格的左上角会有一个绿色小三角作为标志&#xff0c;如B1:B3单元格。 在编程时为什么需要区分普通数字和文本数字呢&#xff…

SVG圆形 <circle>的示例代码

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

.NET 8.0 AOT 教程 和使用 和 .NET ORM 操作

NET AOT编译是一种.NET运行时的编译方式&#xff0c;它与传统的JIT编译方式不同。在传统的JIT编译中&#xff0c;.NET应用程序的代码在运行时才会被编译成本地机器码&#xff0c;而在AOT编译中&#xff0c;代码在运行之前就被提前编译成本地机器码。这样可以在代码运行的时候不…

键盘映射笔记

dumpkeys命令用于显示当前系统中定义的键盘映射表。它可以帮助用户查看和理解系统中的键盘布局和键盘映射规则。 当用户执行dumpkeys命令时&#xff0c;它会读取系统中的键盘映射表文件&#xff08;通常是/etc/keymaps或/etc/console/boottime.kmap.gz&#xff09;&#xff0c;…

Rust unix domain socket

先用起来再说 use std::io::prelude::*; use std::os::unix::net::UnixStream;fn main() {let mut stream: UnixStream;let mut buffer vec![0u8; 4096];match UnixStream::connect("/tmp/hello.world.serv") {Ok(handle) > {stream handle;match stream.write_…

【C#二开业务冠邑】通过界面查看数据来源

前言 重构框架&#xff08;CS【C#】转BS【Java】&#xff09;时&#xff0c;突然发现公司的代码和数据库&#xff0c;有部分都没有写注释&#xff0c;嘎嘎&#xff0c;这不非常影响开发效率&#xff0c;于是乎&#xff0c;开始帮公司整理表结构和数据来源&#xff0c;也从而加…

3D全景视角,足不出户感知真实场景的魅力

近年来&#xff0c;随着科技的快速发展&#xff0c;普通的平面静态视角已经无法满足我们了&#xff0c;不管是视角框架的限制还是片面的环境展示&#xff0c;都不足以让我们深入了解场景环境。随着VR全景技术的日益成熟&#xff0c;3D全景技术的出现为我们提供了全新的视觉体验…