C++中的右值引用

C++中的右值引用

摘要

本文介绍C++中右值引用的含义、以及注意事项。

右值引用的含义

《C++ primer》第5版中说明了右值引用的含义:

所谓右值引用就是必须绑定到右值的引用

举例来说:

int i = 42;
int &r = i; // 左值引用绑定到左值上
int &&rr = i; // 错误,右值引用不能绑定到左值上
int &&rri = i * 42; //正确,i*42是右值

此外,《C++ primer》中还说明了右值引用的重要性质:

只能绑定到一个将要销毁的对象

需要注意的是,右值引用变量本身是左值,所以不能用一个右值引用变量初始化一个右值引用。

int &&rx = rri; //错误,rri是一个右值引用变量,是左值

那么,到底为什么说一个右值引用变量是一个左值呢?左右值的理解就是,

  • 程序员可以取地址的是左值。
  • 程序员不能取地址的是右值。
    这里,rri是一个变量,具有名字,可以取地址,所以说是左值。

左值引用和右值引用的区别

学了左值引用和右值引用,自然要问这两个的区别是什么?左值引用和右值引用的区别就是初始化使用的规则不一样,其余都一样。

左值引用:只能使用左值进行初始化(除了,常量左值引用可以使用字面量初始化)
右值引用:只能使用右值初始化

在使用的时候,左值引用和右值引用无任何区别。

编译器如何对待右值引用?

既然右值引用只能绑定到右值上,并且右值引用变量本身是左值,自然就有以下疑问:
问题1:右值引用绑定的是右值,而右值是将要消亡的,但是右值引用变量本身又是左值,左值就代表着是持久的。那么把编译器是如何实现的?
问题2:按照我的这篇随笔中的理解,我把右值理解成水,把引用理解成标签,那么把一个右值引用(标签)绑定到了右值(水)上,就说不通了,怎么解释?

来看一下汇编代码:


C++中的右值引用

右值引用的反汇编例子


可以看出,当一个右值引用变量绑定到右值的时候,编译器会将右值存储到栈内存中,并且将该地址赋值给右值引用。

也就是说,当一个即将消亡的值被一个右值引用变量绑定时,编译器会先把该值保存到栈上,然后把保存位置的内存地址赋值给右值引用。 从水桶和水的关系解释,编译器先创建了一个水桶,把水倒进水桶,并把标签贴到该水桶上。这就是当一个右值引用绑定到右值时,编译器的做法。

用法

当然,平时使用的话还是无需关心编译器怎么处理的细节,只需要关心什么时候能用,什么时候不能用就行了。
什么时候不能用:

  • 函数返回内部变量的右值引用:
    比如:
int && test() {
    int x = 1;
    return x + 1; // 未定义行为,最好别用
}

什么时候能用:
右值引用主要的用途:

  • 实现移动语义。
  • 实现完美转发。

总结

本文关键点:

  • 右值引用只能绑定到右值上。
  • 右值引用变量是左值。
  • 右值引用变量指向的是一片内存,这片内存中存了值。所以,一个函数不能返回内部值的右值引用。
  • 使用右值引用实现移动语义和完美转发。

参考

原文链接: https://www.cnblogs.com/relaxease/p/16034122.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++中的右值引用

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/188326

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午2:10
下一篇 2023年2月12日 下午2:10

相关推荐