左值右值
void fun(int& a)
{
cout << "fun(int& a)" << endl;
}
void fun(const int& a)
{
cout << "const int& a" << endl;
}
void fun(int&& a)
{
cout << "fun(int&& a)" << endl;
}
template<class T>
void fac(T&& a) //右值引用 称之为行为未定义
{
fun(a);
}
int main()
{
int a = 10;
const int b = 20;
const int& x = b;
const int& y = 20;
fun(a);
fun(b);
fun(10);
return 0;
}
即使我们将 void fun(int&& a){}
删除,fun(10),会去调用所谓的万能引用 void fun(const int& a){}
;也就是说fun(10)会优先调用右值引用,如果没有右值引用,则会退而求其次调用常因用
template<class T>
void fac(T&& a)
{
cout << std::is_lvalue_reference<T>::value << endl;
}
int main()
{
int a = 10;
const int b = 20;
fac(a);
fac(b);
fac(10);
return 0;
}
该模板对无论左值右值都可以进行调用,并且fun(10),在调动中既不属于右值也不属于左值
void fun(int& a)
{
cout << "fun(int& a)" << endl;
}
void fun(const int& a)
{
cout << "const int& a" << endl;
}
void fun(int&& a)
{
cout << "fun(int&& a)" << endl;
}
template<class T>
void fac(T&& a)
{
fun(a);
}
int main()
{
int a = 10;
const int b = 20;
const int& x = b;
const int& y = 20;
fac(a);
fac(b);
fac(10); //进入函数成为了具名变量
return 0;
}
根据上面代码,按常理我们可以分析出,fac(a) 去调用 void fun(int& a),fac(b) 调用 void fun(const int& a),fac( c ) 调用 void fun(int&& a)
在这里我们的 void fac(T&& a)
,变量a属于20的别名,那么一旦右值拥有了名字,就会变成左值继而调用void fun(int& a);
完美转发
系统为了解决上面代码中的问题,给出了一个新的概念:完美转发
void fac(T&& a)
{
//fun(a);
fun(std::forward<T>(a));
}
int main()
{
int a = 10;
const int b = 20;
const int& x = b;
const int& y = 20;
fac(a);
fac(b);
fac(10);
return 0;
}
在整个过程中,可以保持a是20的左值的同时,在进行调用的时候依然可以将其看作一个右值
所谓完美转发(perfect formarding),是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。