当前位置: 首页 > news >正文

15、lambda表达式、右值引用、移动语义

前言

返回值后置

auto 函数名 (形参表) ->decltype(表达式)

lambda表达式

lambda表达式的名称是一个表达式 (外观类似函数),但本质绝非如此

语法规则

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

lambda表达式的本质

  • lambda表达式本质其实是一个类
  • 并且最终返回值为这个类的对象
  • 因此对lambda表达式的调用就是该对象的函数操作符的调用

简写

  • 可以没有返回值类型,将根据return推断
  • 如果连return也没有,则返回值为void
  • 参数为void可以省略不写

捕获表

  • []:不捕获任何外部变量
  • [variable] : 捕获外部变量的值(具备只读属性)
  • [&variable]: 按引用捕获,指定的外部变量
  • [this]: 捕获this指针,访问外部对象的成员
  • [=]: 按值捕获所有的外部变量,也包括this
  • [&]: 按引用捕获所有的外部变量,也包括this
  • [=,&variable]: 按值捕获所有的外部变量包括this,但是指定的外部变量按引用捕获
  • [&,=variable]: 按引用捕获所有的外部变量,也包括 this,但是指定的外部变量按值捕获
// lambda表达式
#include <iostream>
#include <typeinfo>
using namespace std;int Max(int x, int y){return x > y ? x : y;
}int main( void ){int a = 10, b = 20;cout << Max(a,b) << endl;;auto f = [](int x, int y)->int{ return x > y ?  x : y; };// 编译器根据lambda表达式(1)生成一个类 (2)类内定义函数操作符函数 (3)返回这个类的匿名对象/*class Z4mainEUliiE_{public:int operator()(int x, int y){return x > y ?  x : y;}};auto f = Z4mainEUliiE_{};*/cout << "f的类型:" << typeid(f).name() << endl;cout << f(a,b) << endl; // f.operator()(a,b)// lambda表达式可以没有返回值类型,根据return判断cout << [](int x, int y) { return x+y; }(a,b) << endl;/*class X{public:auto operator()(int x, int y)->decltype(x+y){return x + y;}};cout << X{}(a,b) << endl; // cout << X{}.operator()(a,b) << endl;*/ // lambda表达式可以没有返回类型,也没有retrun语句,返回类型为void[](int x, int y){ cout << x << ' ' << y << endl; }(a,b);/*class XX{public:void operator()(int x, int y){cout << x << ' ' << y << endl;}};XX{}(a,b); // XX{}.operator()(a,b)*/// 如果没有形参,可以省略不写[]{ cout << "无聊" << endl;}();/*class XXXX{public:void operator(){cout << "无聊" << endl;} };XXXX{}();  // XXXX().operator()()*/ return 0; 
} 
// lambda表达式 -- 捕获表(捕获lambda表达式外部的变量信息)
#include <iostream>
#include <typeinfo>
using namespace std;int a = 10;class Y{
public:void foo(/* Y* this */ int c = 30 ){cout << "-------------[]----------------" << endl;[](int d = 40){cout << "a=" << a << endl;cout << "b=" << b << endl;
//          cout << "c=" << c << endl; // errorcout << "d=" << d << endl;
//          cout << "e=" << e << endl; // error}();/*class X{public:void operator()(int d = 40)){cout << "a=" << a << endl;cout << "b=" << b << endl;//  cout << "c=" << c << endl; // errorcout << "d=" << d << endl;//  cout << "e=" << this->e << endl; // error}};X{}();*/cout << "-------------[c]----------------" << endl;// 捕获外部变量的值[c](int d = 40){ cout << "c=" << /*++*/c << endl; }();/* class XX{public:XX(int m):c(m){} //这里的c并不是foo函数的形参,而是XX类的一个成员变量void operator()(int d = 40){ cout << "c=" << c << endl; // //这里的c并不是foo函数的形参,而是XX类的一个成员变量}private:const int c; //这里的c并不是foo函数的形参,而是XX类的一个成员变量};XX{c}(); // 这里的c是foo函数的形参c   XX(c).operator()()*/cout << "-------------[&c]----------------" << endl;[&c](int d = 40){ cout << "c=" << ++c << endl; }();cout << "-------------[&c]----------------" << endl;[this](int d = 40){ cout << "e=" << e << endl; }();}private:static int b;int e;
};int Y::b = 20;int main( void ){Y y;y.foo();return 0; 
} 

右值引用

左值 和 右值

  • 可以“取”地址的值就是左值,左值通常具名
  • 不可“取”地址的值就是右值,右值通常匿名
    在这里插入图片描述

左值引用 和 右值引用

  • 左值引用只能引用左值,不能引用右值
int a;
int& b = a; // OK
int c;
int& d = a + c; // ERROR
  • 右值引用只能引用右值,不能引用左值
int&& e = a + c;// OK
int&& f = a; // ERROR
  • 常左值引用,既能引用左值,也能引用右值
const int& g = a + c; // OK
const int& h = a; // OK

没有必要有常右值引用,因为常右值引用,完全可以被常左值引用替代

// 左值/右值    左值引用/右值引用
#include <iostream>
using namespace std;int foo( ) {int m=888;return m;
}int main( void ) {
// 当前作用域的生命期
// 具名内存-->能够取址-->左值|非常左值(无const修饰)
//                           |常左值  (有const修饰)int a = 10;int& ra = a; // okconst int& cra = a; // okconst int b = 10;
//  int& rb = b; // errorconst int& crb = b; // ok// 语句级生命期(引用可以延长右值的生命期)
// 匿名内存-->不能取址-->右值|直接更改右值毫无意义(98/03标准给出结论)
//                           | 11标准认为给了真名就可以改const int& ri = 10; int&& rri  = 10; const int& rf = /*|888|*/foo( ); // (1)分配一块内存空间  (2)生成跳转指令int&& rrf = foo();return 0;
}
//左值引用/右值引用
#include <iostream>
using namespace std;int main( void ) {int a,c;// 左值引用只能引用左值,不能引用右值int& b = a;  // ok
//  int& d = a + c; // error// 右值引用只能引用右值,不能引用左值int&& e = a + c; // oke = 666;         // ok 通过右值引用不会丧失修改目标内存的权限
//  int&& f = a;     // error// 常左值引用(万能引用),既能引用左值,也能引用右值const int& g = a;     // okconst int& h = a + c; // ok
//  g = 666;  // error 但是通过常左值引用会丧失修改目标内存的权限return 0;
}

移动语义

资源的转移 代替 资源的重建

保证功能正确的情况下,做到性能提升

相关文章:

15、lambda表达式、右值引用、移动语义

前言 返回值后置 auto 函数名 (形参表) ->decltype(表达式) lambda表达式 lambda表达式的名称是一个表达式 (外观类似函数)&#xff0c;但本质绝非如此 语法规则 [捕获表] (参数表) 选项 -> 返回类型 { 函数体; }lambda表达式的本质 lambda表达式本质其实是一个类…...

spring boot 实现直播聊天室(二)

spring boot 实现直播聊天室(二) 技术方案: spring bootnettyrabbitmq 目录结构 引入依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.96.Final</version> </dependency>Si…...

alibaba fastjson GET List传参 和 接收解析

之前一直都是 get传的都是单字符串&#xff08;例如 xxxxxxxxx?name{name};name“woaini”;&#xff09;&#xff0c;并没有传list的. GET List传参 问题场景 String url"xxxxxxxx?id{id}"; HashMap<String,Object> param new HashMap<>(); param.pu…...

API自动化测试是什么?我们该如何做API自动化测试呢?

API测试已经成为测试工作中的常规任务之一。为了提高测试效率并减少重复的手工操作&#xff0c;API自动化测试变得越来越重要。本文总结了API自动化测试方面的经验和心得&#xff0c;旨在与读者分享。 掌握自动化技能已经成为高级测试工程师的必备技能。敏捷和持续测试改变了传…...

PyTorch 的 10 条内部用法

欢迎阅读这份有关 PyTorch 原理的简明指南[1]。无论您是初学者还是有一定经验&#xff0c;了解这些原则都可以让您的旅程更加顺利。让我们开始吧&#xff01; 1. 张量&#xff1a;构建模块 PyTorch 中的张量是多维数组。它们与 NumPy 的 ndarray 类似&#xff0c;但可以在 GPU …...

Django、Echarts异步请求、动态更新

前端页面 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>echarts示例</title> <script src"jquery.min.js"></script><script type "text/javascript" src "echarts.m…...

Mac部署Odoo环境-Odoo本地环境部署

Odoo本地环境部署 安装Python安装Homebrew安装依赖brew install libxmlsec1 Python运行环境Pycharm示例配置 Mac部署Odoo环境-Odoo本地环境部署 安装Python 新机&#xff0c;若系统没有预装Python&#xff0c;则安装需要版本的Python 点击查询Python官网下载 安装Homebrew 一…...

【✅面试编程题:如何用队列实现一个栈】

✅面试编程题&#xff1a;如何用队列实现一个栈 &#x1f4a1;典型回答 &#x1f4a1;典型回答 使用两个队列可以实现一个栈&#xff0c;一个队列用来存储栈中的元素&#xff0c;另一个队列用来在pop操作时暂存元素。 上才艺&#xff1a; import java.util.LinkedList; impo…...

Windows本地的RabbitMQ服务怎么在Docker for Windows的容器中使用

1. 进入管理界面 windows安装过程请访问&#xff1a;Windows安装RabbitMQ、添加PHP的AMQP扩展 浏览器访问&#xff1a;http://127.0.0.1:15672/ 2. 创建虚拟主机 上面访问的是 RabbitMQ 的管理界面&#xff0c;可以在这个界面上进行一些操作&#xff0c;比如创建虚拟主机、…...

YOLOv5改进 | 2023卷积篇 | AKConv轻量级架构下的高效检测(既轻量又提点)

一、本文介绍 本文给大家带来的改进内容是AKConv是一种创新的变核卷积&#xff0c;它旨在解决标准卷积操作中的固有缺陷&#xff08;采样形状是固定的&#xff09;&#xff0c;AKConv的核心思想在于它为卷积核提供了任意数量的参数和任意采样形状&#xff0c;能够使用任意数量…...

微信小程序:模态框(弹窗)的实现

效果 wxml <!--新增&#xff08;点击按钮&#xff09;--> <image classimg src"{{add}}" bindtapadd_mode></image> <!-- 弹窗 --> <view class"modal" wx:if"{{showModal}}"><view class"modal-conten…...

uniapp交互反馈api的使用示例

官方文档链接&#xff1a;uni.showToast(OBJECT) | uni-app官网 1.uni.showToast({}) 显示消息提示框。 常用属性&#xff1a; title:页面提示的内容 image&#xff1a;改变提示框默认的icon图标 duration&#xff1a;提示框在页面显示多少秒才让它消失 添加了image属性后。 注…...

XUbuntu22.04之HDMI显示器设置竖屏(一百九十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…...

如何用 Cargo 管理 Rust 工程系列 甲

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/ceMTUzRjDoiLwjn_KfZSrg 这几年 Rust 可谓是炙手可热的新兴编程语言了&#xff0c;而且被投票为最受程序员喜爱的语言。它很现代&#xff0c;专门…...

Windows下ping IP+端口的方法

有两种方法&#xff1a; 1. windows 开通 telnet 参考&#xff1a; https://zhuanlan.zhihu.com/p/570982111 2. 安装插件 参考&#xff1a;Windows下ping IP端口的方法 推荐使用第二种。...

【python】os.getcwd()函数详解和示例

os.getcwd() 是 Python 的一个内建函数&#xff0c;用于获取当前工作目录的路径。这个函数属于 os 模块&#xff0c;需要导入这个模块才能使用它。 import os data_rootos.path.abspath(os.path.join(os.getcwd(),"../.."))# get data root path data_root1os.path.…...

Linux(二十一)——virtualenv安装成功之后,依然提示未找到命令(-bash: virtualenv: 未找到命令)

Linux(二十一)——virtualenv安装成功之后&#xff0c;依然提示未找到命令&#xff08;-bash: virtualenv: 未找到命令&#xff09; 解决办法&#xff1a; 创建软连接 ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv...

RNN介绍及Pytorch源码解析

介绍一下RNN模型的结构以及源码&#xff0c;用作自己复习的材料。 RNN模型所对应的源码在&#xff1a;\PyTorch\Lib\site-packages\torch\nn\modules\RNN.py文件中。 RNN的模型图如下&#xff1a; 源码注释中写道&#xff0c;RNN的数学公式&#xff1a; 表示在时刻的隐藏状态…...

Qt 文字描边(基础篇)

项目中有时需要文字描边的功能 1.基础的绘制文字 使用drawtext处理 void MainWindow::paintEvent(QPaintEvent *event) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.setRenderHint(QPainter::SmoothPixmapTransform, true);painte…...

.360勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

导言&#xff1a; 在数字化时代&#xff0c;.360勒索病毒如影随形&#xff0c;威胁个人和组织的数据安全。本文将深入介绍.360病毒的特征、威胁&#xff0c;以及如何有效地恢复被加密的数据文件&#xff0c;同时提供预防措施&#xff0c;助您更好地保护数字资产。如不幸感染这…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...