在 C++11 中,引入了纯右值(pure rvalue)和将亡值(expiring value)的概念,它们是右值表达式(rvalue expression)的两种子类。

  1. 纯右值:指的是一个表达式,它要么是字面值(如整数、字符、字符串)、要么是一个不具名的临时对象、要么是一个返回右值引用的函数调用表达式,而它们的特点是没有持久的身份或地址,无法被修改或访问。例如::运算表达式产生的临时变量、不和对象关联的原始字面量、非引用返回的临时变量、lambda表达式等都是纯右值。

  2. 将亡值:指的是即将被销毁或离开作用域的对象,其特点是可以被移动,但不能被复制。将亡值是一种特殊的纯右值,其右值引用可以被获取,因此可以实现资源管理的优化,如移动语义。

下面举例说明纯右值和将亡值的概念。

int x = 0;  // x 是左值,可以取地址
int y = x + 1;  // x + 1 是纯右值,没有地址
int &&z1 = x + 1;  // x + 1 是纯右值,可以绑定到右值引用
const int &z2 = x + 1;  // x + 1 是纯右值,可以绑定到 const 引用
int &&z3 = std::move(y);  // y 是将亡值,可以通过 std::move 转移其所有权

在上述例子中,表达式 x + 1 是纯右值,因为它没有持久的身份或地址,不能被修改或访问。而将亡值是一种特殊的纯右值,其右值引用可以被获取,因此可以实现资源管理的优化。

需要注意的是,纯右值和将亡值的概念对于理解 C++11 及其后续版本中的移动语义和完美转发等特性非常重要。

能不能用难一点的例子区别一下纯右值和将亡值?? 

当我们进行函数返回时,可以使用纯右值和将亡值的特性,实现更高效的值传递和返回。

#include <iostream>
#include <string>

std::string foo() {
  std::string str = "Hello";
  return str;  // 返回的是 str 的副本,需要进行复制
}

std::string bar() {
  std::string str = "World";
  return std::move(str);  // 返回的是 str 的右值引用,不需要复制
}

int main() {
  std::string str1 = foo();  // 复制构造 str1,效率较低
  std::string str2 = bar();  // 移动构造 str2,效率更高
  std::cout << str1 + " " + str2 << std::endl;
  return 0;
}

在上述代码中,函数 foo 返回的是一个字符串对象 str 的副本,因此需要进行复制,效率较低。而函数 bar 返回的是字符串对象 str 的右值引用,使用 std::move 转移其所有权,避免了进行复制操作,提高了效率。

需要注意的是,虽然将亡值的右值引用可以被获取,但是在获取后也会失去其所有权,因此不能在获取后继续使用其值。在实际开发中,需要特别注意将亡值的使用。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐