左值与右值

什么是左值?什么是右值?

在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++ 左值与右值 右值引用 引用折叠 => 完美转发的更多相关文章

  1. [c++11]右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  2. [转][c++11]我理解的右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  3. C++11 左值引用和右值引用与引用折叠和完美转发

    1.左值与右值 最感性的认识. 当然,左值也是可以在右边的. 左值是可以被修改的,右值不能. 当然取地址也是. 生存周期一般左值会比右值的长,一般右值都计算时产生的无名临时对象,存在时间比较短. 下面 ...

  4. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案

    本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  5. 第16课 右值引用(3)_std::forward与完美转发

    1. std::forward原型 template <typename T> T&& forward(typename std::remove_reference< ...

  6. Effective Modern C++:05右值引用、移动语义和完美转发

    移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...

  7. (C++)读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔)

    1 /* 2 程序功能:读取一个输入的int型十进制数字的位数,并正序输出每个位上的值(不同数位的值用1个空格字符间隔). 3 例如:当输入985这个数字时,显示如下信息: 4 985是一个3位数字! ...

  8. R_Studio(癌症)以等宽类别值、自定义类别值、等频类别值(分为5类)

    对“癌症.csv”中的肾细胞癌组织内微血管数进行连续属性的离散化处理 增加“微血管数分类1”属性,取值为等宽类别值(分为5类),增加“微血管数分类2”属性,取值为自定义类别值(0~40,41~60,6 ...

  9. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

随机推荐

  1. 微信小程序 canvas导出图片模糊

    //保存到手机相册save:function () { wx.canvasToTempFilePath({ x: , y: , width: , //导出图片的宽 height: , //导出图片的高 ...

  2. HTML/CSS快速入门

    Web概念 JavaWeb 使用java语言开发基于互联网的项目 软件架构 C/S架构:Client/Server 客户端/服务器 用户本地有一个客户端程序,在远程有一个服务端程序 如QQ,英雄联盟. ...

  3. 实现DataTables搜索框查询结果高亮显示

    DataTables是封装好的HTML表格插件,丰富了HTML表格的样式,提供了即时搜索.分页等多种表格高级功能.用户可以编写很少的代码(甚至只是使用官方的示例代码),做出一个漂亮的表格以展示数据.关 ...

  4. ArcEngine ILabelEngineLayerProperties Expression 添加常量

    ArcEngine实现复杂标注的时候,需要结合几个字段并将常量加载表达式中. 开始的时候发现VBScript需要采用“”来括起来常量才能在VB中正常使用,但是 ILabelEngineLayerPro ...

  5. Linux如何查找文件的创建时间

    Linux的文件能否找到文件的创建时间取决于文件系统类型,在ext4之前的早期文件系统中(ext.ext2.ext3),文件的元数据不会记录文件的创建时间,它只会记录访问时间.修改时间.更改时间(状态 ...

  6. python之创建文件写入内容

    https://www.cnblogs.com/evablogs/p/7096686.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  7. java加载properties文件的六中基本方式实现

    java加载properties文件的方式主要分为两大类:一种是通过import java.util.Properties类中的load(InputStream in)方法加载: 另一种是通过impo ...

  8. php中curl返回false的解决办法

    本文介绍一下自己在使用curl中遇到的问题解决办法.希望可以帮助到大家. 原文地址:代码汇个人博客 http://www.codehui.net/info/37.html 首先来看一个封装的curl函 ...

  9. 如莲开发平台(MIS基础框架、Java技术、B/S结构)

    关于     「如莲」是一套MIS类系统基础框架,主要用于各类“管理信息系统”的开发,也适合做网站后台开发.可省去开发时的框架搭建.规范约定.权限管理等基础工作,直接专注于业务功能实现.     「如 ...

  10. VMware安装CentOS7.5

    虚拟机配置: 选择安装方式: 第一行:安装CentOS 7: 第二行:测试这个媒体并安装CentOS 7: 第三行:故障排除: Tips:CentOS 7与CentOS 6网卡名称命名方式有所改变,如 ...