左值和右值

左值l-value(locate-value):储存在内存中,有明确地址,可以被取地址的值。

右值r-value(read-value):不可以被取地址的值,如字面量。

右值有两种类型:

  • 纯右值:非引用返回的临时变量、运算表达式结果是一个不具名的临时变量、字面量等。
  • 将亡值:C++11中的将亡值是随着右值引用的引入而新引入的,将亡值就是返回值为右值引用类型值或者转换为右值引用类型的表达式,如T&& 类型函数的返回值、 std::move 的返回值等,即将结束其生命周期的值。

什么是右值引用?

右值引用是对右值的引用,右值引用可以延长即将被销毁的值的生命周期,即右值的生命周期等同于右值引用的生命周期。

在C++11中,用左值去初始化一个对象或为一个已有对象赋值时,会调用拷贝构造函数或拷贝赋值运算符来拷贝资源,而当用一个右值(包括纯右值和将亡值)来初始化或赋值时,会调用移动构造函数或移动赋值运算符来移动资源,从而避免拷贝,提高效率。当该右值完成初始化或赋值的任务时,它的资源已经移动给了被初始化者或被赋值者,同时该右值也将会马上被销毁(析构)。也就是说,当一个右值准备完成初始化或赋值任务时,它已经“将亡”了。这种右值常用来完成移动构造或移动赋值的特殊任务,扮演着“将亡”的角色,所以C++11给这类右值起了一个新的名字——将亡值。

另外,右值引用若当做参数传递或者当做表达式的时候,由于已经具名化,编译器会将该值视为左值。

万能引用

像auto &&v,模板参数T &&t,在这两种场景下 && 被称作未定的引用类型,需要做自动类型推导。

在这种情况下,只有参数为右值才会进行右值引用,否则即为左值引用

此外 const auto &&v 为右值引用,不是未定义引用类型,不用做类型推导。

move

move的作用是将左值转换为右值,类似static_cast<T&&>(lvalue);使用move后资源的所有权从原来的对象中转移到另一个对象中,期间不发生移动拷贝操作。使用move可以实现对资源复用。

forward

如果使用右值引用作为参数传递时会认定该参数为左值,如果需要传递右值就需要使用forward,forward 也称完美转发,他可以吧左值引用转换成左值,非左值引用转换为右值。

参考资料

Categories:

Tags:

还没发表评论,快来发表第一个评论吧~

发表回复