右值引用

定义

设X为任何一种数据类型，则定义X&&是到数据类型X的右值引用（rvalue reference to X）。传统的引用类型X&被称为左值引用（lvalue reference to X）。例如：
int i;
int &j=i; //傳統的左值引用數據類型的變量並初始化int &&k=std::move(i);  //定義一個右值引用數據類型的變量並初始化。std::move定義於<utility>

完美转发

完美转发也是C++11标准引入右值引用这一概念所要实现的目标之一。

背景

在C++程序设计中，一个常见的类工厂函数，如下例：
template <typename T, typename Arg> 
shared_ptr<T> factory(Arg arg){
    return shared_ptr<T>( new T(arg) );}
参数对象arg在上例中是传值方式传递，这带来了生成额外的临时对象的代价。对于类工厂函数，完美的参数传递应该是引用方式传递。因而，在boost:bind中，参数是左值引用：
template <typename T, typename Arg> 
shared_ptr<T> factory(Arg& arg){
    return shared_ptr<T>( new T(arg) );}
这种实现的问题是形参不能绑定右值实参。如factory<X>(102)将编译报错。进一步解决办法是按常量引用方式传递参数，如下例：
template <typename T, typename Arg> 
shared_ptr<T> factory(const Arg& arg){
    return shared_ptr<T>( new T(arg) );}
这种实现的问题是不能支持移动语义。
形参使用右值引用可以解决完美转发问题。

移动语义与异常

移动语义只是把资源从一个右值对象搬移到被构造或者被赋值对象内部，因此保证不抛出异常是容易实现的。在std::vector这样的容器内实现移动语义，必须显式声明容器元素类的移动构造成员函数、移动赋值运算符成员函数不抛出异常。

右值引用的类型推导

C++中涉及到的右值引用的类型推导，除了上述模板参数类型推导，还有：

typedef的类型推导

typedef也可能会用到引用塌缩规则。例如：
template<typename T>    class Widget {
    typedef T& LvalueRefType;};Widget<int&&> w; // LvalueRefType的类型为int&void f(Widget<int&>::LvalueRefType&& param); //param的类型为int&

decltype类型推导

decltype也可能会用到引用塌缩规则。例如：
int var;decltype(var)&& v1=std::move(var); //类型是int&&