右值引用T&&
绑定到右值。
- 关于右值引用的概念理解
- 右值本身是不可修改的量,但右值引用变量本身是一个左值,有内存地址,生命周期。
- 并不是“先有一个右值,再给它创建一个叫右值引用的东西”,而是“右值引用这种类型,本身就是用来绑定右值的”。
- 右值引用不等同于右值的引用,而是只能对右值进行右值引用.
- 区分这个概念的关键在于,右值引用只能作用于右值,左值是不能进行右值引用的操作的。 如果需要对一个左值进行右值引用操作,那就要用
std::move将之转为右值。
#include <iostream> using namespace std; void func_rvalue(int&& rval) { cout << rval << endl; } //这个函数只能接收右值,因为入参设定为参数的右值引用。只有右值才能被右值引用。左值作为参数输入进行右值引用会编译报错。 int main() { int&& ref_b = 30; // ref_b是右值引用类型,ref_b绑定到右值30。即便ref_b绑定到右值,这个变量本身照样是一个左值。 //因此 &ref_b 是不会报错的,&ref_b可以寻址。 cout << &ref_b << endl; //但func_rvalue(ref_b);会出现编译报错。 //因为 ref_b是左值,无法进行右值引用操作。 func_rvalue(30);//30作为字面量是右值,这样的入参给到函数调用是可行的。 //要想正确实现func_rvalue(ref_b); 应预先对ref_b用std::move(ref_b)进行右值转换。 func_rvalue(std::move(ref_b)); return 0; }
在模板中,T&&和auto&&是万能引用。
#include <iostream>
using namespace std;
template <typename T>
void func(T&& val) {
val += 10;
cout << val << endl;
}
int main() {
int a = 5;
func(a); //万能引用,绑定左值。
func(10); //万能引用,绑定右值。
auto&& ref1 = a;
auto&& ref2 = 20;
return 0;
}
C++中的&&是右值引用,除了在模板和auto&&中可以作为万能引用之外,&&都只能处理右值的引用,涉及到左值的情况要用std::move处理转成右值引用类型。值得注意的是 const/volatile T&&/auto&& 是纯右值引用。(const 和 volatile 可单独修饰,也可组合修饰(const volatile),无论哪种组合,只要附加了这两个限定符,对应的 && 类型就只能是纯右值引用。)