template<class T>
void test(T&& t) {
cout << "test(T&&)" << endl;
}
int main()
{
int a = 10;
test(a);
test(10);
return 0;
}
模板函数的参数是右值引用。为什么还可以接收左值呢?
- 以上这种未定的引用类型(param的类型)称为 universal references,这种类型必须被初始化,而它是左值还是右值则取决于它的初始化,如果被左值初始化,那么它就是左值,反之亦然。那么什么时候是左值,什么时候是右值,就需要进行类型推导才知道。
- 由于存在T&&这种未定的引用类型,当它作为参数时,有可能被一个左值引用或右值引用的参数初始化,这是经过类型推导的T&&类型,相比右值引用(&&)会发生类型的变化,这种变化就称为引用折叠。(《深入应用C++11-代码优化与工程级应用》 — 祁宇 P68 )
- 引用折叠的规则如下:
- 所有右值引用折叠到右值引用上仍然是一个右值引用。(A&& && 变成 A&&)
- 所有的其他引用类型之间的折叠都将变成左值引用。 (A& & 变成 A&; A& && 变成 A&; A&& & 变成 A&)