C++ 左值与右值 右值引用 引用折叠 => 完美转发
左值与右值
什么是左值?什么是右值?
在C++里没有明确定义。看了几个版本,有名字的是左值,没名字的是右值。能被&取地址的是左值,不能被&取地址的是右值。而且左值与右值可以发生转换。
我个人的理解就是在当前作用域下右值是个临时变量。
举例如下:https://blog.csdn.net/wangshubo1989/article/details/50479162
// lvalues:
//
int i = ;
i = ; // ok, i is an lvalue
int* p = &i; // ok, i is an lvalue
int& foo();
foo() = ; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue // rvalues:
//
int foobar();
int j = ;
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
j = ; // ok, 42 is an rvalue
照搬了别人的例子。(尴尬)
右值引用
以前在拜读muduo的时候就遇到过右值引用T&&。当时没详细了解,就知道配合std::move使用,是移动构造函数A(A&& a)中使用的。
后来才知道他其实是右值引用
具体关于move以及移动构造函数我以前以及了解过,也使用比较多,此处不用记录了C++11中移动语义(std::move)和完美转发(std::forward)也有所解释,我更看中他对forward的解释(笑~)
引用折叠 => 完美转发
什么是引用折叠?

来自C++11中移动语义(std::move)和完美转发(std::forward)
不过还是很难理解这和完美转发的实现有什么关联?为什么引用折叠能让forward完美转发参数原来的左值右值属性?
感觉是这文的的实例代码一段讲述了forward的好处,后一段其实是严重引用折叠的,所以我没看懂
//https://en.cppreference.com/w/cpp/utility/forward
#include <iostream>
#include <memory>
#include <utility> struct A {
A(int&& n) { std::cout << "rvalue overload, n=" << n << "\n"; }
A(int& n) { std::cout << "lvalue overload, n=" << n << "\n"; }
}; class B {
public:
template<class T1, class T2, class T3>
B(T1&& t1, T2&& t2, T3&& t3) :
a1_{std::forward<T1>(t1)},
a2_{std::forward<T2>(t2)},
a3_{std::forward<T3>(t3)}
{
} private:
A a1_, a2_, a3_;
}; template<class T, class U>
std::unique_ptr<T> make_unique1(U&& u)
{
return std::unique_ptr<T>(new T(std::forward<U>(u)));
} template<class T, class... U>
std::unique_ptr<T> make_unique2(U&&... u)
{
return std::unique_ptr<T>(new T(std::forward<U>(u)...));
} int main()
{
auto p1 = make_unique1<A>(); // rvalue
int i = ;
auto p2 = make_unique1<A>(i); // lvalue std::cout << "B\n";
auto t = make_unique2<B>(, i, );
}
rvalue overload, n=2 lvalue overload, n=1 B rvalue overload, n=2 lvalue overload, n=1 rvalue overload, n=3
结合此段代码就可以感觉到,虽然B(T1&&,T2&&,T3&&)的参数都是右值引用,结合应用折叠规则,其转入的参数都会保留原有的右值引用和左值引用属性
C++ 左值与右值 右值引用 引用折叠 => 完美转发的更多相关文章
- [c++11]右值引用、移动语义和完美转发
c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...
- [转][c++11]我理解的右值引用、移动语义和完美转发
c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...
- C++11 左值引用和右值引用与引用折叠和完美转发
1.左值与右值 最感性的认识. 当然,左值也是可以在右边的. 左值是可以被修改的,右值不能. 当然取地址也是. 生存周期一般左值会比右值的长,一般右值都计算时产生的无名临时对象,存在时间比较短. 下面 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 第16课 右值引用(3)_std::forward与完美转发
1. std::forward原型 template <typename T> T&& forward(typename std::remove_reference< ...
- Effective Modern C++:05右值引用、移动语义和完美转发
移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...
- (C++)读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔)
1 /* 2 程序功能:读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔). 3 例如:当输入985这个数字时,显示如下信息: 4 985是一个3位数字! ...
- R_Studio(癌症)以等宽类别值、自定义类别值、等频类别值(分为5类)
对“癌症.csv”中的肾细胞癌组织内微血管数进行连续属性的离散化处理 增加“微血管数分类1”属性,取值为等宽类别值(分为5类),增加“微血管数分类2”属性,取值为自定义类别值(0~40,41~60,6 ...
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解 ...
随机推荐
- RxJava2.0入门篇
传统用法:开启子线程去做耗时任务,业务逻辑越复杂,代码嵌套越严重,Rx系列出来很久了,想自己做一个总结,希望能帮到一部分人 观察者模式先提一嘴 这个老模式简直不想说太多,就说一下流程 1创建被观察者 ...
- 本地Windows环境Dubbo搭建测试
Dubbo介绍 Dubbo[]是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 其核心部分包含: 远程通讯: 提供对多种基于长连接的NIO框架抽象封装, ...
- Aspnet mvc移除WebFormViewEngine
为了提高mvc的速度,在Global.asax中移除WebFormViewEngine protected void Application_Start() { RemoveWebFormEngine ...
- RabbitMQ消息模型概览(简明教程)
小菜最近用到RabbitMQ,由于之前了解过其他消息中间件,算是有些基础,所以随手从网上搜了几篇文章,准备大概了解下RabbitMQ的消息模型,没想到网上文章千篇一律,写一大堆内容,就是说不明白到底怎 ...
- [FTP]通过FileZilla在阿里云主机上搭建ftp服务器
前一阵子租了一台服务器主机来玩,正好周末有时间研究了一下怎么搭建ftp server. 准备.首先要下载filezilla client和filezilla server, 下载地址: server: ...
- mybatis常见错误
1.传入单个参数为list时 List<Objects> query(@param("list") List<String> list) <selec ...
- thinkphp封装方法添加跨域请求
function wang_json($data){ //返回JSON数据格式到客户端,包含状态信息 header(' Content-Type:application/json; charset=u ...
- Linux新手随手笔记1.4
计划任务服务程序 计划任务 at 命令 一次性的 crond 服务 周期性的 23:29执行reboot命令(重启服务器) at -l 查看当前的计划任务 at ...
- .NET开源快速开发框架Colder发布 (NET452+AdminLTE版)
.NET开源快速开发框架Colder(NET452+AdminLTE版) 引言 半年前将基于Easyui的快速开发框架开源,三个版本(NET4.52,NETCore和NET4.0)总共荣获200+星, ...
- 创建pandas和sqlalchemy的j交互对象,方便于日常的数据库的增删改查(原创)
#导入第三方库sqlalchemy的数据库引擎 from sqlalchemy import create_engine #导入科学计算库 import pandas as pd #导入绘图库 imp ...