c++11标准(2)右值引用的衍生产物

欢迎来到博主的专栏:c++杂谈
博主ID:代码小豪

文章目录

    • 万能引用模板
    • 右值引用到底是左值还是右值
    • 完美转发

万能引用模板

当c++11推出右值引用之后,我们所写的模板函数可以写成这样:

template<class T>
T&& Universal_template(T&& data)
{//......
}

根据直觉判断,这个模板函数的应该是一个右值引用类型的参数和返回值的函数,但是事实真是如此吗?

c++将T&&类型的模板称为万能引用模板,即该参数根据传递的值,可以实例化出左值引用和右值引用两种形式。即使用了万能引用模板的模板函数,可以同时具有接收左值和右值的能力,根据左值或右值的原本类型,该函数模板会实例化出四种版本,分别为:

T& Universal_template(T& data)
{//......
}
const T& Universal_template(const T& data)
{//......
}
T&& Universal_template(T&& data)
{//......
}
const T&& Universal_template(const T&& data)
{//......
}

我们可以用下面的测试来证明这个特性:

template<class T>
void func1(T& data)
{cout << "void func1(T&)" << endl;
}template<class T>
void func1(const T& data)
{cout << "void func1(const T&)" << endl;
}template<class T>
void func1(T&& data)
{cout << "void func1(T&&)" << endl;
}template<class T>
void func1(const T&& data)
{cout << "void func1(const T&&)" << endl;
}template<class T>
void Universal_template(T&& data)
{func1(data);
}
int main()
{int a = 1;//左值const int b = 2;//左值常量Universal_template(a);//int &Universal_template(b);//const int &Universal_template(move(a));//int &&Universal_template(move(b));//const int &&return 0;
}

这段测试的逻辑很简单,就是通过传递不同类型左值和右值,看看万能模板是不是真的能接收左值和右值,并且根据func1模板的实例化结果来判断传递的参数是否正确。

比如传递一个const int的右值,那么Universal_template函数就会实例化成(const int &&)类型的参数,然后就会调用func1(const T &&)的重载版本的函数,然后向屏幕输出"void func1(const T&&)”以代表万能引用模板确实能接收左值和右值的引用。

根据上面的说法,如果Universal_template函数是一个万能引用模板,那么这段测试的正确输出应该是

void func1(T&)
void func1(const T&)
void func1(T&&)
void func1(constT&&)

但是运行这段测试的真实结果却让人大跌眼镜。
在这里插入图片描述
为什么会这样呢?

右值引用到底是左值还是右值

啥?右值引用当然是右值了,难道还能是左值吗?

我只能说,右值引用的引用对象一定是右值,但是右值引用本身不是右值,而是左值。

嘶,这句话咋这么绕呢,我们还是用一个测试来证明吧。

void is_rvalue(int& val)
{cout << "rrc是一个左值" << endl;
}void is_rvalue(int&& val)
{cout << "rrc是一个右值" << endl;
}int main()
{int c = 10;int&& rrc = move(c);//引用对象是右值is_rvalue(rrc);return 0;
}

运行结果为:
在这里插入图片描述
这说明在c++中,右值引用的对象是右值,但是右值引用本身是一个变量,因此是一个左值。

完美转发

通过分析可知,右值引用本身是一个左值是导致前面万能引用模板的测试失效的原因,因为无论是T&&类型的data,还是const T&&类型的data,其本身是一个左值,因此传递给func1函数时,其实例化出的函数只会是const T&,或者T&的类型。

为了解决这个问题,c++推出一个forward()的模板函数、通常我们将这个函数称为“完美转发”

lvalue (1)	
template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
rvalue (2)	
template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;

这个函数的作用是,可以判断该左值到底是左值引用,还是右值引用。(毕竟右值引用本身也是左值)。那么上面那个万能引用模板的问题也随之解决了。


template<class T>
void Universal_template(T&& data)
{func1(forward<T> (data));//如果data是一个右值引用类型,那么传递的也是右值//如果data是一个左值引用类型,那么传递的则是一个左值
}

在这里插入图片描述

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

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

相关文章

[000-01-008].第08节:Sentinel 环境搭建

1.Sentinel的构成&#xff1a; 核心库-后台默认的端口是8719控制台-前台默认的是8080端口 2.2.搭建Sentinel环境&#xff1a; a.下载Sentinel&#xff1a; 1.sentinel官方提供了UI控制台&#xff0c;方便我们对系统做限流设置。可以在GitHub下载 b.下载后运行Sentinel&#…

【virtuoso】AMS数模混合仿真

一、新建Verilog文件 1.1 新建functional 文件 1.2 编写Verilog文件 module phv (ckv ,rst_n ,phv_n );input ckv ;input rst_n ;output reg [10:0] phv_n;always (posedge ckv) beginif(rst_n)phv_n < 11b0;elsephv_n <…

【C++】多态的认识和理解

个人主页 文章目录 ⭐一、多态的概念&#x1f384;二、多态的定义及实现1.多态的构成2.实现多态的条件3.虚函数的概念4.虚函数的重写和覆盖5.析构函数的重写6.协变7.override和 final关键字8.重载、重写/覆盖、隐藏这三者的区别 &#x1f3e0;三、纯虚函数和抽象类的关系&#…

纯血鸿蒙NEXT常用的几个官方网站

一、官方文档 https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/Readme-CN.md刚入门查看最多的就是UI开发模块&#xff0c;首先要熟悉组件使用 二、官方API参考 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/development-i…

JVM 调优篇7 调优案例2-元空间的优化解决

一 元空间 1.1 功能概述 方法区&#xff08;Method Area&#xff09;与 Java 堆一样&#xff0c;是各个线程共享的内存区域&#xff0c;它用于存储已被虚拟机加载的类信息、常量、即时编译器编译后的代码等数据。虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分&#xf…

【操作系统】二、进程管理:4.死锁(银行家算法、系统安全状态、静态分配策略、资源有序分配法)

五、死锁 文章目录 五、死锁1.产生1.1产生情况1.2产生的4个必要条件 2.处理方式2.1预防死锁2.1.1破坏互斥条件2.1.2破坏请求和保持条件2.1.3破坏不可抢占条件2.1.4破坏循环等待条件 2.2避免死锁2.2.1系统安全状态❗2.2.2银行家算法 2.3检测死锁2.4解除死锁 死锁&#xff1a;资源…

ubuntu安装wordpress(基于LNMP环境)

参考链接 Ubuntu安装LNMP 安装步骤 环境需要LNMP环境&#xff0c;如果没有安装可以参考ZATA—LNMP简单安装 在mysql中设置wordpress所用的用户名和密码 #1. 登录mysql mysql -uroot -p #2. 创建wordpress数据库 create database wordpress; #3. 创建新用户user&#xff0c;…

使用Java实现一个简单的B树

1.B树简介 B树是一个搜索树&#xff0c;数据结构可以抽象成如二叉树一样的树&#xff0c;不过它有平衡、有序、多路的特点。 平衡&#xff1a;所有叶子节点都在同一层。有序&#xff1a;任一元素的左子树都小于它&#xff0c;右子树都大于它。多路&#xff1a;B树的每个节点最多…

【Linux】文件权限与类型全解:你的文件安全指南

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;文件权限与类型全解&#xff1a;你的文件安全指南 &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题…

激光雷达点云处理—学习随记

一、激光雷达基本概念 激光雷达&#xff08;Light Detection and Ranging&#xff0c;LiDAR&#xff09;&#xff0c;是一种发射激光&#xff08;可见光-近红外&#xff09;于被瞄准物体表面并记录反射光被信号接收器接收到的时间以测定距离的方法。激光雷达通过以下公式确定物…

基于springboot酒店管理系统

酒店管理系统 552酒店管理系统 摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;…

【MySQL】查询语句之inner、left、right、full join 的区别

前言&#xff1a; INNER JOIN 和 OUTER JOIN 是SQL中常用的两种连接方式&#xff0c;用于从两表活多表中提取相关的数据。两者区别主要在于返回的 结果集 如何处理 匹配 与 不匹配 的行。 目录 1、INNER JOIN 2、OUTER JOIN 3、总结 1、INNER JOIN 称为内连接&#xff0c;只…

【Python机器学习】NLP信息提取——命名实体与关系

我们希望计算机能够从文本中提取信息和事实&#xff0c;从而略微理解用户所说的内容。例如&#xff0c;当用户说“提醒我星期一浏览***.org网站”&#xff0c;我们希望这句话触发当天后下一个周一的日程或者提醒的操作。 要触发上述操作&#xff0c;需要知道“我”代表一种特定…

5.内容创作的未来:ChatGPT如何辅助写作(5/10)

引言 在信息爆炸的时代&#xff0c;内容创作已成为连接品牌与受众、传递信息与知识、以及塑造文化与观念的重要手段。随着数字媒体的兴起&#xff0c;内容创作的需求日益增长&#xff0c;对创作者的写作速度和质量提出了更高的要求。人工智能&#xff08;AI&#xff09;技术的…

感谢问界M9一打二十,让我们买到这么便宜的BBA

文 | AUTO芯球 作者 | 雷慢 国产豪华车&#xff0c;终于扬眉吐气了&#xff0c; 你敢信吗&#xff1f;在50万以上豪华车中&#xff0c; 现在问界M9一款车的月销量&#xff0c; 是其他前20名销量的总和&#xff01; 要知道&#xff0c;它的对手是各种宝马、奔驰、雷克萨斯的…

私有化通讯工具:安全、高效、个性化,重塑企业沟通生态

在当今数字化时代&#xff0c;即时通讯已成为企业日常运营中不可或缺的一部分。随着数据安全和隐私保护意识的日益增强&#xff0c;越来越多的企业开始寻求更加安全、可控的沟通方式。私有化聊天工具应运而生&#xff0c;以其独特的核心优势&#xff0c;为企业构建了一个安全、…

VMware vSphere 8.0 Update 3b 发布下载,新增功能概览

VMware vSphere 8.0 Update 3b 发布下载&#xff0c;新增功能概览 vSphere 8.0U3 | ESXi 8.0U3 & vCenter Server 8.0U3 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-8-u3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页…

【Leetcode】70. 爬楼梯

题目来源 70. 爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶…

webpack5 构建优化方案看这篇就够了!【Node.js进阶】

无论在面试还是内部晋升&#xff0c;webpack 构建优化方案 一直都是非常重要的部分。 webpack5构建加持 一、项目完成目标二、搭建项目1. 安装koa、koa/router &#xff08;如果已经配置可路过&#xff09;2. 创建入口文件3. 安装构建依赖4. 在项目根目录添加 .babelrc 文件5. …

一般在写SQL时需要注意哪些问题,可以提高查询的效率?

很多人写SQL按照自己喜好&#xff0c;没有规则意识&#xff0c;这对于自主查询影响不大&#xff0c;你爱怎么搞就怎么搞&#xff0c;一旦涉及到提交任务或团队共享&#xff0c;就不能乱写了&#xff0c;会浪费资源影响到开发效率&#xff0c;严重的甚至会服务器瘫痪。 提几个关…