0 特征
T&&
就是一个万能引用,表示既可以是右值引用,也可以是左值引用,二者取一。
具体取左值还是右值取决于初始化的参数。
例如:
template<typename T>
void f(T&& param);
Widget w;
f(w);//左值引用
f(std::move(w));//右值引用
1 区分于右值引用
1.1 万能引用
当使用场景为类型推导的函数模版的形参时,为万能引用。
场景一:
template<typename T>
void f(T&& param);
例子(源自vector源代码):
template<class T, class Allocator = allocator<T>>
class vector{
public:
template<class... Args>
void emplace_back(Arg&&... args);//用到可变模版
}
场景二:
class Widget{
};
Widget&& var1 = Widget();
auto&& var2 = var1;
声明为auto&&
类型的变量都是万能引用,并且肯定涉及类型推到并有正确的形式。
在C++14的lambda表达式中可以声明auto&&
形参,例如:
auto f = [](auto&& func, auto&&... params){};
1.2 右值引用
下面的例子均是右值引用:
void f(Widget&& parm);//不涉及类型推导
template<typename T>
void f(std::vector<T>&& param);//不是T&&的形式
template<typename T, class Allocator = allocator(T)>
class vector{
public:
void push_back(T&& x);//未涉及到类型推导
}
2 总结
万能引用并非一种全新的引用,而是满足如下条件的右值引用:
- 1,类型推导会区分左值和右值。【T的左值推导为T&,右值推导为T】
- 2,会发生引用折叠。