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

news2024/11/27 1:27:56

基本用法

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属性。

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

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

相关文章

Ubuntu20.04安装CUDA、cuDNN、tensorflow2可行流程(症状:tensorflow2在RTX3090上运行卡住)

最近发现我之前在2080ti上运行好好的代码&#xff0c;结果在3090上运行会卡住很久&#xff0c;而且模型预测结果完全乱掉&#xff0c;于是被迫研究了一天怎么在Ubuntu20.04安装CUDA、cuDNN、tensorflow2。 1.安装CUDA&#xff08;包括CUDA驱动和CUDA toolkit&#xff0c;注意此…

【MySQL】MySQL的安装与配置环境变量(使其在控制台上使用)

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《MySQL》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&a…

删除文件要谨慎!如何在Linux中删除目录或文件

删除目录和文件是任何操作系统中最基本但最重要的功能之一。在Linux中,如果运行的是窗口环境,则可以使用文件管理器应用程序查找和删除文件。也许你是通过SSH远程登录的,或者你的Linux计算机没有安装GUI,或者你想对你要删除的内容有更多的控制权。与Linux中的任何东西一样,…

【微服务 Spring Cloud Alibaba】- Nacos 服务注册中心

目录 1. 什么是注册中心&#xff1f; 1.2 注册中心的作用 2. SpringBoot 整合 Nacos 实现服务注册中心 2.1 将服务注册到 Nacos 2.2 实现消费者 3. 服务列表各个参数的含义、作用以及应用场景 1. 什么是注册中心&#xff1f; 注册中心是微服务架构中的一个重要组件&…

NoSQL数据库以及架构介绍

文章目录 一. 什么是NoSQL&#xff1f;二. NoSQL分类三. NoSQL与关系数据库有什么区别四. NoSQL主要优势和缺点五. NoSQL体系框架 其它相关推荐&#xff1a; 系统架构之微服务架构 系统架构设计之微内核架构 鸿蒙操作系统架构 架构设计之大数据架构&#xff08;Lambda架构、Kap…

Selenium学习(Java + Edge)

Selenium /səˈliːniəm/ 1. 简介 ​ Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Safari、Google Chrome、Opera、Edge等。 ​ 适用于自动化测试&#x…

Linux期末复习——文件I/O编程

Linux系统调用以及用户编程接口 三者关系 系统调用、API以及系统命令之间关系&#xff1a; 什么是文件描述符&#xff1f; 是一个非负整数&#xff0c;索引值 打开或者创建一个文件的时候&#xff0c;内核会向进程返回一个文件描述符 读写文件时&#xff0c;会向函数传递一个文…

ModuleNotFoundError: No module named ‘paddle.fluid.incubate.fleet‘

在使用rocketqa的时候可能会遇到下面的问题&#xff1a; 问题&#xff1a; 解决方法&#xff1a; 这完全是paddlepaddle的问题。 在rocketqa/utils/optimization.py出现下面的语句&#xff0c;这个时候直接把出错的注释掉就可以&#xff0c;因为它完全没有用到。&#xff08;…

Win10奇怪的部分文字乱码问题

1.打开Windows设置的时间和语言 2.打开区域下方的的其他日期、时间和区域设置 3.点击更改日期、时间或数字格式。切换到管理 4.点击更改系统区域设置&#xff0c;取消Beta版&#xff1a;使用Unicode UTF-8提供全球语言支持。 按提示重启电脑即可。

Windows电脑怎么下载桌面便签小工具?

Windows电脑是日常办公中常用的工具&#xff0c;电脑上可以安装许多软件来辅助日常办公&#xff0c;其中桌面便签工具可以为大家记录很多日常办公中的各项工作计划&#xff0c;而且便签软件通常可以悬挂于电脑桌面显示&#xff0c;方便大家一边工作一边查看备忘记录。 谈及Win…

探索网络攻击:ARP断网、ARP欺骗和DNS欺骗实验解析

目录 前言 一、ARP概述 1.1 什么是ARP 1.2 ARP协议的基本功能 1.3 ARP缓存表 1.4 ARP常用命令 二、ARP断网实验 三、ARP欺骗实验 3.1 内网截获图片 3.2 HTTP账户密码获取 四、DNS欺骗实验 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&…

OpenGL ES入门教程(一)编写第一个OpenGL程序

OpenGL ES入门教程&#xff08;一&#xff09;编写第一个OpenGL程序 前言 从本文开始我将参考学习OpenGL ES应用开发实践指南 Android卷 [&#xff08;美&#xff09;KevinBrothaler著]&#xff08;提取码: 394m&#xff09;&#xff0c;并基于自己的理解以更加通俗易懂的方式…

[.NET]桃源网络硬盘 v7.4

桃源网络硬盘是一个以.net进行开发的网络硬盘系统源码。 开发环境&#xff1a;Microsoft.NET Framework SDK 运行要求&#xff1a; Windows 2003及以上版本 或 Windows XP及以上版本&#xff0c;安装 .Net Framework 要求上传目录有写权限 请将其放在虚拟目录或单独的网页空间…

Kubernetes包管理工具Helm简介及使用

文章目录 前言技术积累什么是HelmHelm的核心概念Helm可以解决哪些痛点Helm中文官方文档 Helm安装Helm安装nginx用例写在最后 前言 大家都知道K8S是云原生devops的一大利器&#xff0c;可以直接让我们的中间件、应用服务直接运行在云端&#xff0c;让我们可以只关心自身的业务功…

【Unity】【VR开发疑难】Unity运行就报无法启动XR Plugin

【现象】 连接Link后运行Unity的VR项目Link也无反映&#xff0c;Unity控制台报&#xff1a;无法启动XR Plugin&#xff0c;并说是由于Oculus头盔未连接导致。 【分析】 打开Oculus PC客户端&#xff0c;发现状态是连接正常。重启机器后&#xff0c;提示Oculus没有出于RunTim…

概念解析 | 揭开心电图测量的神秘面纱

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:ECG的测量原理 揭开心电图测量的神秘面纱 How to read an ECG – Physical Therapy Reviewer 1. 背景介绍 心电图(ECG)是记录心脏电活动的过程,它反映了心脏在收缩和舒张期间的…

新一代构建工具Vite-xyphf

一、什么vite? vite:是一款思维比较前卫而且先进的构建工具,他解决了一些webpack解决不了的问题——在开发环境下可以实现按需编译&#xff0c;加快了开发速度。而在生产环境下&#xff0c;它使用Rollup进行打包&#xff0c;提供更好的tree-shaking、代码压缩和性能优化&…

创建javaEE项目(无maven),JSP(九大内置对象)、Servlet(生命周期)了解

一、Servlet和jsp 0.创建web项目(无maven)&#xff1a; 1.创建一个普通的java项目 2.项目根目录右键&#xff0c;添加模板 3.配置tomcat服务器 4.配置项目tomcat依赖 1.Servlet(Server Applet)服务端小程序 用户通过浏览器发送一个请求&#xff0c;服务器tomcat接收到后&…

串口通信(7)判断数据帧头来接收一串数据

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

微信小程序:两层循环的练习,两层循环显示循环图片大图(大图显示、多层循环)

效果 代码分析 外层循环 外层循环的框架 <view wx:for"{{info}}" wx:key"index"></view> wx:for"{{info}}"&#xff1a;这里wx:for指令用于指定要遍历的数据源&#xff0c;即info数组。当遍历开始时&#xff0c;会依次将数组中的每…