跟我学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){}   //右值引用,没有推导过程
 };

五、总结

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

相关推荐
c2385611 小时前
C++列表初始化与变量类型推导
开发语言·c++
折戟不必沉沙11 小时前
C++四种类型转换是什么
开发语言·c++
John_ToDebug12 小时前
WeakPtr 与 Raw 指针:UAF 如何识别、如何处理、以及 Chromium 的设计哲学
c++·chrome·ai
fqbqrr13 小时前
2606C++,方便的调试类
c++
我不是懒洋洋13 小时前
从零实现一个RPC框架:远程调用与服务治理
c++
困意少年13 小时前
从统一初始化到移动语义:C++11 为什么是现代 C++ 的起点
c++
stolentime13 小时前
CF2066D1 Club of Young Aircraft Builders (easy version)题解
c++·算法·动态规划·组合数学
Jun62614 小时前
QT(1)-C/C++库生成和调用
c语言·开发语言·c++·qt
小欣加油14 小时前
leetcode41 缺失的第一个正数
数据结构·c++·算法·leetcode
智者知已应修善业14 小时前
【51单片机按键控制1分钟正计时倒计时暂停复位】2024-1-2
c++·经验分享·笔记·算法·51单片机