1、引用折叠:
约定:只有&& && = &&,沾上一个&就变左值引用了。
T && && ==>T &&
T && & ==>T &
T & && ==>T &
T & & ==>T &
引用折叠会在四种语境中发生:模板实例化,auto类型生成,创建和运用typedef和别名声明,以及decltype。
万能引用就是在类型推导过程会区分左值和右值,以及会发生引用折叠的语境中的右值引用。
当编译器在引用折叠的语境下生成引用的引用时,结果会变成单个引用。如果原始的引用中有任一引用为左值引用,则结果为左值引用,否则,结果为右值引用。
2、万能引用:
universal reference
概念:使用T&&类型的形参既能绑定右值,又能绑定左值。
T&&在代码里并不总是右值引用。
要注意的是,仅仅是当发生自动类型推导(如函数模板的类型自动推导,或auto关键字)的时候,T&&才是universal references。
3、右值引用:
右值引用就是对右值的引用,给右值取别名。
右值引用引用右值,会使右值被存储到特定的位置。
也就是说,右值引用变量其实是左值,可以对它取地址和赋值(const右值引用变量可以取地址但不可以赋值,因为 const 在起作用)。
4、为什么是左值引用?
template<typename T>
void f(T&& a){
g(a)
//g(static_cast<T &&>(a));
//g(static_cast<T>(a)); 这样写也可以
}
// 版本 1
template<typename T>
void g(T &){ cout << "T&" << endl; }
// 版本 2
template<typename T>
void g(T &&){ cout << "T&&" << endl; }
int a;
f(0);
f(a);
输出:
T&&
T&
但是0是数字,是右值,为什么进去后就成了左值?
我的分析:因为f(0)根据万能引用,参数a是右值引用;随后传到g(a),参数a虽然是右值引用但本身是左值,左值传到g(a) 调用g (T &);
参考:
https://blog.csdn.net/qq_35836473/article/details/116303789
https://blog.csdn.net/qq_36553387/article/details/116915635