C++11 左值引用和右值引用与引用折叠和完美转发
2021/7/23 12:37:07
本文主要是介绍C++11 左值引用和右值引用与引用折叠和完美转发,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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 左值引用和右值引用与引用折叠和完美转发的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-20获取apk的md5值有哪些方法?-icode9专业技术文章分享
- 2024-11-20xml报文没有传 IdentCode ,为什么正常解析没报错呢?-icode9专业技术文章分享
- 2024-11-20如何知道代码有没有进行 Schema 验证?-icode9专业技术文章分享
- 2024-11-20Mycat教程:新手快速入门指南
- 2024-11-20WebSocket入门:轻松掌握WebSocket基础
- 2024-11-19WebSocket入门指南:轻松搭建实时通信应用
- 2024-11-19Nacos安装资料详解:新手入门教程
- 2024-11-19Nacos安装资料:新手入门教程
- 2024-11-19升级 Gerrit 时有哪些注意事项?-icode9专业技术文章分享
- 2024-11-19pnpm是什么?-icode9专业技术文章分享