1.左值与右值

最感性的认识。

当然,左值也是可以在右边的。

左值是可以被修改的,右值不能。

当然取地址也是。

生存周期一般左值会比右值的长,一般右值都计算时产生的无名临时对象,存在时间比较短。

下面还有一种情况也要区分。

2.左值引用和右值引用

左值引用:可以引用一个对象,有时候也可以绑定一个右值。

右值引用:只能引用右值。

1左值引用示例

看以下代码,比较正常。

	int a = 3;
int &p1 = a; // 左值引用

若左值引用右值将报错

但加上const就可以引用了

2右值引用示例

不能把左值绑定到右值,但使用move可以把左值转换右值就可以绑定

示例1

示例2

示例3

理解了上边知识,接下来是引用折叠规则,

3.引用折叠

先看演示代码

#include <iostream>
using namespace std; using lRef = int&; //左值引用
using rRef = int&&; //右值引用 int main(int argc, char **argv)
{
is_lvalue_reference<lRef &>::value ?
cout << "lRef & 左值引用" << endl :
cout << "lRef & 右值引用" << endl; is_lvalue_reference<lRef &&>::value ?
cout << "lRef && 左值引用" << endl :
cout << "lRef && 右值引用" << endl; is_rvalue_reference<rRef &>::value ?
cout << "rRef & 右值引用" << endl :
cout << "rRef & 左值引用" << endl; is_rvalue_reference<rRef &&>::value ?
cout << "rRef && 右值引用" << endl :
cout << "rRef && 左值引用" << endl; return 0;
}

调试结果

这就是引用折叠规则。

这怎么理解呢,看下图

可以看到只有都是右值引用的时候才是右值引用,当然只有一个右值引用的情况下自然而然也是右值引用。

这是就引用折叠。

4.完美转发

主要用于参数转发时是左值传入还是右转入

考虑以下代码

#include <iostream>
using namespace std; template<typename T>
void Fun1(T& v)
{
cout << "左值引用调用" << v << endl;
} template<typename T>
void Fun1(T&& v)
{
cout << "右值引用调用" << v <<endl;
} template<typename T>
void Fun(T&& v)
{
Fun1(v);
} int main(int argc, char **argv)
{
int a = 3; Fun(a); return 0;
}

主函数里给Fun传入a,根据上边知识,a是一个左值,看调试结果是调用哪一个重载版本Fun1

结果跟预想的一样,接下来更改换右值传入。

int main(int argc, char **argv)
{ Fun(5); return 0;
}

调试结果

我们发现跟想象中不一样!!!

这时候该怎么办。

c++11中提供了一个用于完美转发的函数forward。

还提供了一个move函数,用于把左值变成右值的方法。

forward会根据引用折叠规则得出传入的是左值引用还是右值引用

接下来只需更改一下Fun函数,其他的不变

template<typename T>
void Fun(T&& v)
{
Fun1(forward<T>(v));
}

调试结果

发现跟我们预想一样了。

完美转发完整示例

#include <iostream>
using namespace std; template<typename T>
void Fun1(T& v)
{
cout << "左值引用调用" << v << endl;
} template<typename T>
void Fun1(T&& v)
{
cout << "右值引用调用" << v <<endl;
} template<typename T>
void Fun(T&& v)
{
Fun1(forward<T>(v));
} int main(int argc, char **argv)
{
int a = 1;
Fun(a);
Fun(move(a)); const int b = 2;
Fun(b);
Fun(move(b)); Fun(5); return 0;
}

调试结果

5.结语

学无止境。

---End

C++11 左值引用和右值引用与引用折叠和完美转发的更多相关文章

  1. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  2. C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

    这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...

  3. c++11 左值引用、右值引用

    c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...

  4. 左值与右值,左值引用与右值引用(C++11)

    右值引用是解决语义支持提出的 这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运 ...

  5. C++11的左值引用与右值引用总结

    概念 在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容):当对象被用作左值的时候,用的是对象的身份(在内存中的位置).左值有持久的状态,而右值要 ...

  6. C++11左值引用和右值引用

    转载:https://www.cnblogs.com/golaxy/p/9212897.html C++11的左值引用与右值引用总结 概念 1.&与&&  对于在C++中,大家 ...

  7. C++11常用特性介绍——左值引用、右值引用

    一.左值.右值 1)左值:可以放在赋值号左侧.可以被赋值的值:左值必须要在内存中有实体. 2)右值:必须放在赋值号右侧.取出值赋值给其它变量:右值可以在内存中也可以在CPU寄存器中. 二.引用 引用是 ...

  8. 【C/C++开发】C++11:左值引用VS右值引用

    左值引用VS右值引用 左值引用对于一般的C++程序员再熟悉不过,但对于右值引用(C++0X新特性),就稍微有点不知所云 左值VS右值 在定义变量的时候,经常会用到左值和右值,比如:int a = 1; ...

  9. C++的左值,右值,左值引用,右值引用

    参考大神链接: https://blog.csdn.net/u012198575/article/details/83142419 1.左值与右值 https://msdn.microsoft.com ...

随机推荐

  1. 大规模数据处理Apache Spark开发

    大规模数据处理Apache Spark开发 Spark是用于大规模数据处理的统一分析引擎.它提供了Scala.Java.Python和R的高级api,以及一个支持用于数据分析的通用计算图的优化引擎.它 ...

  2. 工作流中的流程追溯!详细解析Activiti框架中的历史组件

    Activit中的历史简介 历史: Activiti中的一个组件,可以捕获发生在进程执行中的信息并永久的保存.与运行时数据不同的是,当流程实例运行完成之后它还会存在于数据库中 历史实体对象有5个: H ...

  3. 10: java数据结构和算法: 构建哈夫曼树, 获取哈夫曼编码, 使用哈夫曼编码原理对文件压缩和解压

    最终结果哈夫曼树,如图所示: 直接上代码: public class HuffmanCode { public static void main(String[] args) { //获取哈夫曼树并显 ...

  4. springmvc——基于xml的异常映射和基于注解的异常映射

    SpringMVC提供了基于XML和基于注解两种异常映射机制.这两种异常映射不能够只使用一个,他们需要一起使用.因为有些异常是基于注解异常映射捕获不到的. 在springmvc中,一个请求如果是由&l ...

  5. SpringBoot2配置文件application.yaml

    源码基于SpringBoot 2.4.4 1.认识配置文件 1.1 配置文件的加载 创建SpringBoot项目的时候,会自动创建一个application.properties文件,该文件是Spri ...

  6. 「csp-s模拟测试(9.18)」Set·Read·Race

    昨天考试考得有点迷??? 一看内存限制,T1 64MB T2 16MB 当场懵比......... T1 set 考场打的背包问题和随机化,其实能randA掉,但不小心数组开小了????(长记性!!! ...

  7. NOIP模拟测试20「周·任·飞」

    liu_runda出的题再次$\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%$ 任 题解 题目中为什么反复强调简单路径,没有环 没有环的图中点数-边数=联通块数 前缀和维护边 ...

  8. 20201123 实验一《Python程序设计》实验报告

    20201123 2020-2021-2 <Python程序设计>实验一报告 课程:<Python程序设计> 班级:2011班 姓名:晏鹏捷 学号:20201123 实验教师: ...

  9. Gym 101147G 第二类斯特林数

    大致题意: n个孩子,k场比赛,每个孩子至少参加一场比赛,且每场比赛只能由一个孩子参加.问有多少种分配方式. 分析: k>n,就无法分配了. k<=n.把n分成k堆的方案数乘以n的阶乘.N ...

  10. 学堂在线《Java程序设计(2021春)》系列笔记——前言

    写在前面 目录 写在前面 这个系列是什么 为什么要做这篇博客 我是谁(其实不重要) 其他 这个系列是什么 这是关于学堂在线<Java程序设计(2021春)>(清华大学-郑莉教授)的个人同步 ...