C++中的右值引用 - rvalue-reference

C++ Details

  • rvalue-reference
  • std::move

右值引用

声明语法

1
2
3
4
int a = 1;
int && b = a + 1 // && after typename is called rvalue reference,
int && c = 2; // instead of & after typename which is called lvalue reference
int && d = std::move(a);

在这里,a 是一个 lvalue,其具有长生命周期,而非临时对象,而随后的 b, c 的右边都为临时对象(a + 1 与字面量 2)

这里特殊的是 d,使用了 std::move,将 a 转为 rvalue,变为临时对象

左、右值引用的区别与应用

对于左值引用以及右值引用在使用上并无太大区别,当我们修改一个左值引用时,我们修改其绑定的原对象,右值引用也是如此,两者的区别主要在于生命周期的不同,lvalue 是长期的对象,而 rvalue 是临时的对象

在实践当中,我们通常在函数传参时使用常对象引用传值(call-by-reference-to-a-constant, i.e., call-by-constant reference),形式为 const T & <var>,这是左值引用,因此我们只能传递左值,通常情况在我们将外部现有的对象传入函数时没有问题,但当我们需要处理一个字面量/临时对象,即右值的时候,这种函数签名无法顺利传递参数,这往往出现在我们将函数返回值直接作为参数输入下一个函数时出现,为了避免拷贝,我们可以在此时应用右值引用,形式为 T && <var>

在这里不加 const 是由其核心用途(支持移动语义,需要修改所引用的对象)决定的。右值引用绑定的对象(临时对象或可移动的左值)允许被安全修改,而 const 会禁止这种修改,与移动语义的设计目标冲突。因此,右值引用通常以 non-const 形式出现在函数签名中。