C++ 11添加了一种称为右值引用的新类型引用。右值引用是一个只能用右值初始化的引用。使用单个&符号创建左值引用,但使用双&符号创建右值引用:
int x = 5;int &lref = x; // 使用左值x初始化左值引用
int &&rref = 5; // 使用右值5初始化右值引用
无法使用左值初始化右值引用。
右值引用有两个有用的属性。首先,右值引用将它们初始化的对象的生命周期延长到右值引用的生命周期(对const对象的左值引用也可以这样做)。其次,非常量右值引用允许您修改右值!我们来看看一些例子:
#include <iostream>
class Fraction{
private:
int m_numerator;
int m_denominator;
public:
Fraction(int numerator = 0, int denominator = 1) : m_numerator(numerator),m_denominator(denominator) { }
friend std::ostream& operator<<(std::ostream& out, const Fraction &f1)
{
out << f1.m_numerator << "/" << f1.m_denominator;
return out;
}};
int main()
{
Fraction &&rref = Fraction(3, 5);
// r-value reference to temporary Fraction
std::cout << rref << '\n';
return 0;
} // rref (and the temporary Fraction) goes out of scope here
该程序输出:
3/5
作为一个匿名对象,Fraction(3,5)通常会在定义它的表达式的末尾超出范围。但是,由于我们用它初始化一个右值引用,它的持续时间会延长到块的结尾。然后我们可以使用该右值引用来输出Fraction的值。现在让我们来看一个不太直观的例子:
#include <iostream>
int main()
{
int &&rref = 5;
// because we're initializing an r-value reference with a literal, a temporary with value 5 is created here
rref = 10;
std::cout << rref; return 0;
}
该程序输出:
10
虽然使用数字值初始化右值引用然后能够更改该值可能看起来很奇怪,但是当使用数字初始化右值时,从整数构造临时值以使引用引用临时值对象,而不是数字值。右值引用不经常以上述任何一种方式使用。