一、万能引用
template <typename T>
void TestRValue(T&& nValue)
{
cout << nValue << endl;
}
void main(){
TestRValue(10);
int a = 10;
TestRValue(a);
}
针对TestRValue函数,加了模板类型T后,既能接收左值,为左值引用,又能接收右值作为参数,做右值引用。
const关键字会剥夺万能引用资格,例如:void TestRValue(cosnt T&& nValue){} 这个函数只能传右值。
template <typename T>
class A{
public:
void testfunc(T&& x){}
};
void main(){
A<int> a;
i = 10;
a.testfunc(i);
}
这种类中的函数属于右值引用,不是万能引用。因为这是成员函数,T主要给类模板实例化,实例化后testfunc函数参数类型就已经存在了,不是主要给函数实例化。
二、引用折叠
在万能引用中,如果用左值对TestRValue函数调用,按照道理来说,T会被推断为int&:
TestRValue(int& &&nValue){...},但实际上这种类型语法是不成立的,因此就有了引用折叠(C++11):->TestRValue(int& nValue){...}
将函数参数分成两部分(四种情况):
三、转发和完美转发
概念:在调用模板函数种,参数类型不变的传递给被调用函数。
void yy(int&& y) {
cout << 1 << endl;
}
template <typename T>
void xx(T&& x) {
yy(x); //报错:无法将参数 1 从“T”转换为“int &&”
yy(forward<int>(x));
}
void main() {
xx(1);
}
xx函数中,调用yy,yy(x);这是错误的,因为x 虽然是右值类型,但形参是左值,没有在前面加&&时的形参x是左值类型。调用不了yy函数。
通过forward<int>(x)后就按照右值传了。