【6】c++11新特性(稳定性和兼容性)—>Lambda表达式

基本用法

lambda表达式是c++最重要也是最常用的特性之一,这是现代编程语言的一个特点,lambda表达式有如下的一些优点:
(1)声明式的编成风格:就地匿名定义目标函数活着函数对象,不需要额外写一个命名函数或者函数对象;
(2)简洁:避免了代码膨胀和功能分散;
(3)在需要的时间和地点实现功能闭包,是程序更加灵活。
lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。lambda表达式的语法形式简答归纳如下:

[capture](params)opt->ret{body;}

capture:变量捕获列表;
params:参数列表,类似函数参数;
opt:函数选项;
ret:返回值类型;
body:函数体;
1.捕获列表[]:捕获一定范围内的变量;
2.参数列表():和普通函数的参数列表一样,如果没有参数列表可以不写。

auto f = [](){return 1};
auto f = []{return 1};  

3.opt:不需要时可以省略

  • mutable:可以修改按值传递进来的拷贝(注意时能修改拷贝,而不是值本身);
  • exception:指定函数抛出的异常,如抛出整数类型的异常,可以使用throw。
    4.返回值类型:在c++11中,lambda表达式的返回值是通过返回值后置语法来定义的。
    5.函数体:函数的实现,这部分不能省略,但函数体可以为空。

捕获列表

  • [] : 不捕捉任何变量;
  • [&] : 捕获外部作用域中所有变量,并作为引用在函数体内使用(按引用捕获);
  • [=] : 捕获外部作用域中所有变量,并作为副本在函数体内使用(按值捕获);拷贝的副本在匿名函数体内部是只读的;
  • [=,&foo] : 按值捕获外部作用域中所有变量,并按照引用捕获外部变量foo;
  • [bar] : 按值捕获bar变量,同时不捕获其他变量;
  • [&bar] : 按引用捕获bar变量,同时不捕获其他变量;
  • [this] : 捕获当前类中的this指针。
    让lambda表达式拥有和当前类成员函数同样的访问权限;
    如果已经使用了&或者=,默认添加此选项。
类中使用lambda
#include <iostream>

class Test
{
public:
    void output(int x, int y)
    {
        auto x1 = [] {return 1; };  //ok
        auto x1 = [] {return m_number}; //error,没有捕获外部变量,因此不能使用m_number
        auto x2 = [=] {return m_number + x + y; }; //ok,以值拷贝方式的方式捕获所有外部变量
        auto x3 = [this] {return m_number; }; //ok,捕获this指针,可访问对象内部成员
        auto x4 = [&] {return m_number + x + y; }; //ok,以引用方式捕获所有外部变量
        auto x5 = [this] {return m_number + x + y; }; //error,没有捕获x,y,所以不能使用x,y
        auto x6 = [this, x, y] {return m_number + x + y; };//ok,
        auto x7 = [this] {return m_number++; }; //ok,正常捕获this指针,并且可以修改对象内部变量的值
    }
    int m_number = 100;
};

int main()
{
    std::cout << "Hello World!\n";
}
函数中使用lambda
int main(void)
{
    int a = 10, b = 20;
    auto f1 = [] {return a; };  // error,未捕获a
    auto f2 = [&] {return a++; }; // ok,引用方式捕获
    auto f3 = [=] {return a; };   // ok,值拷贝,只读
    auto f4 = [=] {return a++; };  //error,值拷贝,只读,不可以修改
    auto f5 = [a] {return a + b; }; // error,未捕获b
    auto f6 = [a, &b] {return a + (b++); }; // ok,
    auto f7 = [=, &b] {return a + (b++); }; // ok

    return 0;
}

注:在匿名函数内部,需要通过lambda表达式的捕获列表控制如何捕获外部变量,以及访问哪些变量。默认状态下lambda表达式无法修改通过复制方式捕获外部变量,如果希望修改这些外部变量,需要通过引用的方式进行捕获。

在这里插入图片描述
为什么m_number_1可以修改,m_number_2不可以修改?
在这里插入图片描述
在这里插入图片描述

返回值

c++中允许省略lambda表达式的返回值类型

// 完整的lambda表达式定义
auto f = [](int a) -> int   //int类型可以忽略不写
{
    return a+10;  
};

// 忽略返回值的lambda表达式定义
auto f = [](int a)
{
    return a+10;  
};

如果不指定lambda表达式的返回值,编译器会根据return语句自动推导返回值类型,但需要注意的是lambda表达式不能通过列表初始化自动推导出返回值类型

// ok,可以自动推导出返回值类型
auto f = [](int i)
{
    return i;
}

// error,不能推导出返回值类型
auto f1 = []()
{
    return {1, 2};	// 基于列表初始化推导返回值,错误
}

函数本质

使用lambda表达式捕获列表捕获外部变量,如果希望去修改按值捕获的外部变量,那么应该如何处理呢?这就需要使用mutable选项,被mutable修改时lambda表达式就算没有参数也要谢敏参数列表,并且可以去掉按值捕获的外部变量的只读(const)属性。
在这里插入图片描述
最后再剖析一下,为什么通过值拷贝的方式捕获外部变量是只读的:
1.lambda表达式的类型在c++11中会被看成是带operator()的类,即仿函数;
2.按照c++标准,lambda表达式的operator()默认是const的,一个const成员函数是无法修改成员变量值的。
mutable选项的作用就是取消const属性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker离线部署

docker离线部署 1、目的 在可以连接互联网的情况下&#xff0c;可以在线安装Docker《Linux下Docker安装部署》&#xff0c;如果遇到内网服务器就没有办法进行在线安装&#xff0c;那么需要使用离线安装的方法。 2、下载安装包 创建工作文件夹&#xff1a; mkdir /opt/dock…

【错误解决方案】Error: module ‘cv2‘ has no attribute ‘SURF‘

1. 错误提示 python-opencv高版本中&#xff0c;AttributeError: module cv2 has no attribute SURF问题&#xff1b; 错误提示&#xff1a;Error: module ‘cv2‘ has no attribute ‘SURF‘ 2. 解决方案 解决&#xff1a;将sift cv2.SIFT()替换为&#xff1a;sift cv2.x…

vue3引入并加载unity工程的两种方式

1、使用unity-webgl插件 npm i unity-webglunity打包后的build文件夹是这样的 需要手动删除.unityweb这个后缀&#xff0c;完成后放在vue3项目的根目录下的public文件夹下。 下面是引入unity的vue组件,其中实例化UnityWebgl时的参数地址直接引用上面的对应文件地址 <scri…

源码角度分析Java 循环中删除数据为什么会报异常

一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出&#xff1a;java.util.ConcurrentModificationException 异常&#xff0c;例如&#xff1a;如下所示程序&#xff1a; public class RmTest {public sta…

刷题学习记录

[RoarCTF 2019]Easy Java1 一开始是一个登陆页面&#xff0c;看着有点想用sql注入先试一遍&#xff0c;但是题目已经给出了这是关于Java的 直接查看源码&#xff0c;发现参数要用POST的方式上传 点击进入新页面 百度查了一下这是web.xml 泄露 解题先知WEB-INF WEB-INF是java…

报修软件有什么用?企业如何做好设备管理与维护?

在当今的商业环境中&#xff0c;设备设施的维护和管理已经成为企业运营的重要环节。无论是学校、酒店、物业等大型企事业单位&#xff0c;还是运维集成商、制造工厂等企业单位&#xff0c;都需要对设备设施进行有效的管理。报修软件作为一种智能化的解决方案&#xff0c;为设备…

基于springboot实现疫情防控期间外出务工人员信息管理系统项目【项目源码+论文说明】

基于springboot疫情防控期间外出务工人员信息管理系统 摘要 网络的广泛应用给生活带来了十分的便利。所以把疫情防控期间某村外出务工人员信息管理与现在网络相结合&#xff0c;利用java技术建设疫情防控期间某村外出务工人员信息管理系统&#xff0c;实现疫情防控期间某村外出…

太极培训机构展示服务预约小程序的作用如何

太极是适合男女老幼的&#xff0c;很多地方也有相关的学校或培训机构&#xff0c;由于受众广且不太受地域影响&#xff0c;因此对培训机构来说&#xff0c;除了线下经营外&#xff0c;线上宣传、学员获取和发展也不可少。 接下来让我们看下通过【雨科】平台制作太极教培服务预…

如何确认目标期刊被SCI或EI收录?

原创内容&#xff0c;仅供参考&#xff0c;欢迎大家批评指正&#xff01; 目录 通过Web of Science查询SCI期刊1. 登录Web of Science2. 查找目标期刊3. 查看期刊信息 通过Scopus查询EI期刊1. 登录Scopus2. 查找目标期刊3. 查看期刊信息 参考 通过Web of Science查询SCI期刊 1…

Netty第一部

一、select和epoll原理分析 外设设备网卡、鼠标、键盘等通过总线写到内存中&#xff0c;中间就有DMA拷贝&#xff0c;操作系统怎么知道内存中有数据了&#xff0c;这就需要操作系统通过中断机制确定&#xff0c;如果有中断信号过来&#xff0c;cpu会首先打断用户程序执行&…

加州大学提出 PromptAgent 帮忙我们高效的使用 ChatGPT

本心、输入输出、结果 文章目录 加州大学提出 PromptAgent 帮忙我们高效的使用 ChatGPT前言加州大学团队提出了可以自动优化 Prompt 的框架 —— PromptAgentPromptAgent 原理论文 实例介绍PromptAgent 框架设计PromptAgent 的策略优化过过程PromptAgent 的结果是否具备普适性弘…

文心一言4.0对比ChatGPT4.0有什么优势?

目录 总结 文心一言4.0的优势 文心一言4.0的劣势 免费分享使用工具 后话 生成式AI的困境 “不会问”“不会用”“不敢信” 为什么要出收费版本&#xff1f; 目前使用过国内的文心一言3.5和WPS AI&#xff0c;国外的ChatGPT4.0。 文心一言和其他国内产品相比&#xff0…

SpringCloud(三) Ribbon负载均衡

SpringCloud(二) Eureka注册中心的使用-CSDN博客 在SpringCloud(二)中学习了如何通过Eureka实现服务的注册和发送,从而通过RestTemplate实现不同微服务之间的调用,加上LoadBalance注解之后实现负载均衡,那负载均衡的原理是什么呢? 目录 一, 负载均衡 1.1 负载均衡原理 1.2 源…

【Unity编辑器扩展】艺术字/自定义图片字体生成工具

艺术字在游戏中很常用&#xff0c;由于普通字体样式过于平淡&#xff0c;制作花里胡哨的文字图片作为游戏字体使用&#xff0c;这就是艺术字。 不依赖第三方工具&#xff0c;仅使用Unity自带的Custom Font 一张艺术字图集就能实现这个功能&#xff0c;但是为了便于使用&#…

【AI视野·今日Robot 机器人论文速览 第六十一期】Tue, 24 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Tue, 24 Oct 2023 Totally 50 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Robot Fine-Tuning Made Easy: Pre-Training Rewards and Policies for Autonomous Real-World Reinforcement Learning Autho…

【数据结构】数组和字符串(十三):链式字符串的基本操作(串长统计、查找、复制、插入、删除、串拼接)

文章目录 4.3 字符串4.3.1 字符串的定义与存储4.3.2 字符串的基本操作&#xff08;链式存储&#xff09;1. 结构体2. 初始化3. 判空4. 串尾添加5. 打印6. 串长统计7. 查找8. 复制9. 插入10. 删除11. 串拼接12. 销毁13. 主函数14. 代码整合 4.3 字符串 字符串(String)是由零个或…

2023年CCF中国开源大会“大模型时代的智能化软件工程新范式”分论坛成功举行...

2023年CCF中国开源大会“大模型时代的智能化软件工程新范式”分论坛于10月21日在湖南长沙成功举行。本次论坛聚焦大模型时代的智能化软件新生态以及相应的软件工程新范式&#xff0c;邀请了多位来自学术界和工业界的专家进行分享和交流&#xff0c;共设置了5个主题报告和1个Pan…

K8S删除资源后一直处于Terminating状态无法删除解决方法

原因 使用kubectl delete 删除某命名空间是一直处于Terminating状态无法删除&#xff0c;首先排查了该命名空间下是否还存在deployment pod等资源发现没有后&#xff0c;等了很久还是无法删除后发现是因为该名称空间的“finalizers”字段有值导致 Finalizer&#xff08;终结器…

【OpenCV实现图像梯度,Canny边缘检测】

文章目录 概要图像梯度Canny边缘检测小结 概要 OpenCV中&#xff0c;可以使用各种函数实现图像梯度和Canny边缘检测&#xff0c;这些操作对于图像处理和分析非常重要。 图像梯度通常用于寻找图像中的边缘和轮廓。在OpenCV中&#xff0c;可以使用cv2.Sobel()函数计算图像的梯度…

JVM虚拟机:如何调整堆空间的大小?

对内存的调优 如上所示,从物理角度来说呢,堆内存就是蓝色的区域,从逻辑角度来说,堆内存包含这个红色的部分,调优肯定是条物理的大小了,我们先来看一下物理内存的大小是多少? 如上所示,我们通过maxMemory获取到java虚拟机试图使用的最大内存量,默认为物理内存的1/4,比我…