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;
}

移动语义

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

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

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

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

相关文章

列表标签的介绍与使用

列表的作用&#xff1a; 整齐、整洁、有序&#xff0c;它作为布局会更加自由和方便。 根据使用情景不同&#xff0c;列表可以分为三大类&#xff1a;无序列表、有序列表和自定义列表 无序列表 <ul> 标签表示 HTML 页面中项目的无序列表&#xff0c;一般会以项目符号呈…

小黑子——springBoot基础

springBoot简单学习 一、SpringBoot简介1.1 springBoot快速入门1.1.1 开发步骤1.1.2 对比1.1.3 官网构建工程1.1.3 SpringBoot工程快速启动 1.2 springBoot概述1.2.1 起步依赖I. 探索父工程II. 探索依赖III. 小结 1.2.2 程序启动1.2.3 切换web服务器-jetty 二、配置文件2.1 配置…

Multisim电路仿真软件使用教程

安装直接参考这篇文章&#xff1a;Multisim 14.0安装教程 软件管家公众号里有很多软件&#xff0c;需要的可以去找下然后安装&#xff0c;这里用的是14.0版本。 这里有个大神的详细教程&#xff0c;可以参考&#xff1a; Multisim软件使用详细入门教程&#xff08;图文全解&…

DiffiT

本文首发于AIWalker&#xff0c;欢迎关注。 https://arxiv.org/abs/2312.02139 https://github.com/NVlabs/DiffiT 扩散模型以其强大的表达能力和高样本质量在许多领域得到了新的应用。对于样本生成&#xff0c;这些模型依赖于通过迭代去噪生成图像的去噪神经网络。然而&#x…

es6 相关面试总结

1、es6 是什么 新一代的js 语言标准&#xff0c;对其核心做了升级优化&#xff0c;更加适合大型应用开发。 2、箭头函数优缺点 优点&#xff1a; 1.代码优化 2.this 指向不会变动&#xff0c;永远指向其父元素 缺点&#xff1a; 1.没有arguments 参数 2.不能通过 appl…

2023年11月10日 Go生态洞察:十四年Go的成长之路

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

[山东大学操作系统课程设计]实验四+实验五

0.写在前面&#xff1a; 为什么这次把两个实验放在一起写了&#xff0c;因为实验五的要求就是在实验四的基础上完成实现的。但是我得实现说明&#xff0c;我的实验四虽然完成了要求&#xff0c;但是无法在我自己的实验四的基础上完成实验五&#xff0c;这是一个很大的问题&…

免费的SEO外链发布工具,提升排名的利器

互联网已经成为信息传播和商业发展的重要平台。而对于拥有网站的个人、企业来说&#xff0c;如何让自己的网站在搜索引擎中脱颖而出&#xff1f;SEO&#xff08;Search Engine Optimization&#xff09;作为提高网站在搜索引擎中排名的关键手段. 什么是SEO外链&#xff1f; S…

class064 Dijkstra算法、分层图最短路【算法】

class064 Dijkstra算法、分层图最短路【算法】 算法讲解064【必备】Dijkstra算法、分层图最短路 code1 743. 网络延迟时间 // Dijkstra算法模版&#xff08;Leetcode&#xff09; // 网络延迟时间 // 有 n 个网络节点&#xff0c;标记为 1 到 n // 给你一个列表 times&…

Linux(centos)学习笔记(初学)

[rootlocalhost~]#:[用户名主机名 当前所在目录]#超级管理员标识 $普通用户的标识 Ctrlshift放大终端字体 Ctrl缩小终端字体 Tab可以补全命令 Ctrlshiftc/V复制粘贴 / &#xff1a;根目录&#xff0c;Linux系统起点 ls&#xff1a; #list列出目录的内容&#xff0c;通常用户查看…

Word插件-好用的插件-一键设置字体--大珩助手

常用字体 整理了论文、公文常用字体 整理了常用的论文字体&#xff0c;可一键设置当前节或选择的文字的字体 字体设置 包含字体选择、字体颜色 特殊格式 包含首字下沉、段落分栏、统一宽度、双行合一、上标切换、下标切换、转为全角、转为半角、挖词填空、当前日期、大写金…

思科最新版Cisco Packet Tracer 8.2.1安装

思科最新版Cisco Packet Tracer 8.2.1安装 一. 注册并登录CISCO账号二. 下载 Cisco Packet Tracer 8.2.1三. 安装四. 汉化五. cisco packet tracer教学文档六. 正常使用图 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新…

uniApp项目的创建,运行到小程序

一、项目创建 1. 打开 HBuilder X 2. 右击侧边栏点击新建&#xff0c;选择项目 3. 填写项目名&#xff0c;点击创建即可 注&#xff1a;uniapp中如果使用生命周期钩子函数&#xff0c;建议使用哪种 ?(建议使用Vue的) 二、运行 1. 运行前先登录 2. 登录后点击 manifest.js…

YOLOv8 目标过线计数

使用 Ultralytics YOLOv8 进行目标计数 🚀 实际应用场景 物流水产养殖使用 Ultralytics YOLOv8 进行传送带包裹计数使用 Ultralytics YOLOv8 在海中进行鱼类计数请使用最新代码(2023年12月8日后),旧版本不支持! 示例 “目标计数示例” 目标计数 from ultralytics

公有云迁移研究——AWS Route53

大纲 1 什么是Route 532 Route 53能做些什么# 3 通过DNS托管来实现分流3.1 创建DNS托管3.2 对托管创建记录对流量进行分配 4 通过流量策略来对流量进行分流4.1 创建流量策略 5 对比两者的区别6 推荐 在给客户从本地机房往AWS迁移的过程中&#xff0c;我们接到如下需求&#xff…

SpringBoot 项目 Jar 包加密,防止反编译

1场景 最近项目要求部署到其他公司的服务器上&#xff0c;但是又不想将源码泄露出去。要求对正式环境的启动包进行安全性处理&#xff0c;防止客户直接通过反编译工具将代码反编译出来。 2方案 第一种方案使用代码混淆 采用proguard-maven-plugin插件 在单模块中此方案还算简…

[香橙派]orange pi zero 3 烧录Ubuntu系统镜像——无需HDMI数据线安装

一、前言 本文我们将介绍如何使用orange pi zero 3 安装Ubuntu系统&#xff0c;本文相关步骤均参考自开发手册。 二、实施准备 根据开发手册中所提到的&#xff0c;我们应该拥有如下配件: 1.orange pi zero 3 开发板 2.TF 卡——最小 8GB 容量的 class10 级或以上的高速闪迪卡。…

错题总结(四)

1.【一维数组】输入10个整数&#xff0c;求平均值 编写一个程序&#xff0c;从用户输入中读取10个整数并存储在一个数组中。然后&#xff0c;计算并输出这些整数的平均值。 int main() {int arr[10];int sum 0;for (int n 0; n < 10; n){scanf("%d", &arr…

58.Nacos源码分析2

三、服务心跳。 3.服务心跳 Nacos的实例分为临时实例和永久实例两种&#xff0c;可以通过在yaml 文件配置&#xff1a; spring:application:name: order-servicecloud:nacos:discovery:ephemeral: false # 设置实例为永久实例。true&#xff1a;临时; false&#xff1a;永久ser…

Nginx负载均衡实战

&#x1f3b5;负载均衡组件 ngx_http_upstream_module https://nginx.org/en/docs/http/ngx_http_upstream_module.html upstream模块允许Nginx定义一组或多组节点服务器组&#xff0c;使用时可以通过多种方式去定义服务器组 样例&#xff1a; upstream backend {server back…