C++11新特性之 rvalue Reference(右值引用)
最后更新于:2022-04-01 06:32:22
右值引用可以使我们区分表达式的左值和右值。
C++11引入了右值引用的概念,使得我们把引用与右值进行绑定。使用两个“取地址符号”:
~~~
int&& rvalue_ref = 99;
~~~
需要注意的是,只有左值可以付给引用,如:
~~~
int& ref = 9;
~~~
我们会得到这样的错误: “invalid initialization of non-const reference of type int& from an rvalue of type int”
我们只能这样做:
~~~
int nine = 9;
int& ref = nine;
~~~
看下面的例子,你会明白的:
~~~
#include <iostream>
void f(int& i) { std::cout << "lvalue ref: " << i << "\n"; }
void f(int&& i) { std::cout << "rvalue ref: " << i << "\n"; }
int main()
{
int i = 77;
f(i); // lvalue ref called
f(99); // rvalue ref called
f(std::move(i)); // 稍后介绍
return 0;
}
~~~
右值有更隐晦的,记住如果一个表达式的结果是一个暂时的对象,那么这个表达式就是右值,同样看看代码:
~~~
#include <iostream>
int getValue ()
{
int ii = 10;
return ii;
}
int main()
{
std::cout << getValue();
return 0;
}
~~~
这里需要注意的是 getValue() 是一个右值。
我们只能这样做,必须要有const
~~~
const int& val = getValue(); // OK
int& val = getValue(); // NOT OK
~~~
但是C++11中的右值引用允许这样做:
~~~
const int&& val = getValue(); // OK
int&& val = getValue(); // OK
~~~
现在做一个比较吧:
~~~
void printReference (const int& value)
{
cout << value;
}
void printReference (int&& value)
{
cout << value;
}
~~~
第一个printReference()可以接受参数为左值,也可以接受右值。
而第二个printReference()只能接受右值引用作为参数。
In other words, by using the rvalue references, we can use function overloading to determine whether function parameters are lvalues or rvalues by having one overloaded function taking an lvalue reference and another taking an rvalue reference. In other words, C++11 introduces a new non-const reference type called an rvalue reference, identified by T&&. This refers to temporaries that are permitted to be modified after they are initialized, which is the cornerstone of move semantics.
~~~
#include <iostream>
using namespace std;
void printReference (int& value)
{
cout << "lvalue: value = " << value << endl;
}
void printReference (int&& value)
{
cout << "rvalue: value = " << value << endl;
}
int getValue ()
{
int temp_ii = 99;
return temp_ii;
}
int main()
{
int ii = 11;
printReference(ii);
printReference(getValue()); // printReference(99);
return 0;
}
/*----------------------
输出
lvalue: value = 11
rvalue: value = 99
----------------------*/
~~~