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

一、右值引用

在C++11中出现了右值引用,想知道右值引用,就必须知道右值。在前面分析过左右和消亡值等类型(见“左值和右值再谈”),其实右值就是为了废物利用,而既然利用的好,就有了和左值一样的引用,也就是右值引用。
右值引用仅绑定右值,用于可移动对象的应用,其形式类似于 type&&。

二、万能引用

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

三、区别

在C++的应用中,一般模板编程中万能引用比较多而普通编程中右值引用比较多。那么如何具体的判断是万能引用还是右值引用呢?可以使用下面几点:
1、右值引用,必须传递右值,否则编译无法通过;而万能引用左右值均可传递
2、万能引用不能有const修饰符,否则成为右值引用
3、万能引用必须有一个推导的过程,这也意味着上面说的模板中应用比较多
4、auto一般有一个推导过程,所以auto 绑定时也是万能引用
5、一般右值会使用std::move来处理而万能引用使用std::forward

另外还有几个注意点:
1、应该避免对万能引用的函数进行重载,因为之所以称为万能引用,就是因为其可以精确匹配到具体的数据类型,再做重载没有什么 意义。
2、对引用折叠在万能引用中的处理
3、类和继承中构造函数重载中的万能引用问题处理,需要显示的使用const或限制条件(如enable_if)等来与万能引用区分

四、例程

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

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

五、总结

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

你可能感兴趣的:(C++11,C++,c++)