跟我学C++中级篇——右值引用和万能引用

一、右值引用

在C++11中出现了右值引用,想知道右值引用,就必须知道右值。在前面分析过左右和消亡值等类型(见"左值和右值再谈"),其实右值就是为了废物利用,而既然利用的好,就有了和左值一样的引用,也就是右值引用。

右值引用仅绑定右值,用于可移动对象的应用,其形式类似于 type&&。

二、万能引用

万能引用,就是既可以传右值也可以传递左值,既然都可以使用,所以叫万能引用。万能引用也使用类似T&&的形式。既然右值引用和万能引用都使用相同的类似形式,那么如何区分二者就是一个问题了。

三、区别

在C++的应用中,一般模板编程中万能引用比较多而普通编程中右值引用比较多。那么如何具体的判断是万能引用还是右值引用呢?可以使用下面几点:

1、右值引用,必须传递右值,否则编译无法通过;而万能引用左右值均可传递

2、万能引用不能有const修饰符,否则成为右值引用

3、万能引用必须有一个推导的过程,这也意味着上面说的模板中应用比较多

4、auto一般有一个推导过程,所以auto 绑定时也是万能引用

5、一般右值会使用std::move来处理而万能引用使用std::forward

另外还有几个注意点:

1、应该避免对万能引用的函数进行重载,因为之所以称为万能引用,就是因为其可以精确匹配到具体的数据类型,再做重载没有什么 意义。

2、对引用折叠在万能引用中的处理

3、类和继承中构造函数重载中的万能引用问题处理,需要显示的使用const或限制条件(如enable_if)等来与万能引用区分

四、例程

说得再清楚也有理解上的差别,现在看几个例子就明白了:

c 复制代码
 template<typename T>
 void f(T&& t);      //万能引用
 ​
 auto&& var2 = v1;  //万能引用,auto推导和模板推导产生的结果一样
 
 template<typename T>
 class A{
 template<typename N>
   void test(N&&n){}   //万能引用
 };
 
 int && a = 100;      //右值引用
 template<typename T>
 void f(std::list<T>&& t);      //右值引用
 
 template<typename T>
 class A{
   void test(T&&t){}   //右值引用,没有推导过程
 };

五、总结

细节决定成败,这句话不是没有道理的。一些小的基础的问题,往往是解决一些疑难问题的入手之处。综合运用各种基础技术就可以形成更高层次的抽象应用,这个在模板元编程中体现的就非常明显。往往很多方法都知道什么意思,但组合起来就不知道了,这其实还是基础不太牢靠,只是僵硬的学会了而没有活学活用。

相关推荐
mit6.8241 小时前
[openvela] Hello World :从零开始的完整实践与问题复盘
c++·嵌入式硬件
啊阿狸不会拉杆3 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路3 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
曙曙学编程4 小时前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件
△曉風殘月〆4 小时前
Visual Studio中的常用调试功能(下)
c++·ide·visual studio·调试
武当豆豆5 小时前
C++编程学习(第25天)
开发语言·c++·学习
minji...8 小时前
C++ string类(STL简介 , string类 , 访问修改字符)
开发语言·c++
Forward♞8 小时前
Qt——文件操作
开发语言·c++·qt
十五年专注C++开发8 小时前
CMake进阶: CMake Modules---简化CMake配置的利器
linux·c++·windows·cmake·自动化构建
winds~10 小时前
【git】 撤销revert一次commit中的某几个文件
linux·c++