前置知识:万能引用、引用折叠
1.转发
#include <iostream>
using namespace std;
template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q) // 函数模板,万能引用
{
// f是要转发的目标函数
// 20是右值,T为int类型,t为int&&类型
// i是左值,Q为int&类型,q为int&类型
f(t, q);
}
void myfunc(int x, int& y)
{
x += 10;
y += 10;
cout << "x = " << x << ", y = " << y << endl;
return;
}
int main()
{
int i = 100;
FuncTemplate(myfunc, 20, i);
cout << "i = " << i << endl;
return 0;
}
上面代码中的函数模板可以实现 myfunc(int x, int& y)
的转发,但是不能完成 myfunc(int&& x, int& y)
的转发,这是因为 t
虽然是 int&&
类型,但 t
本身是个左值,不能被右值引用 x
接收。
#include <iostream>
using namespace std;
template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q) // 函数模板,万能引用
{
// f是要转发的目标函数
// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用x接收
// i是左值,Q为int&类型,q为int&类型
f(t, q);
}
void myfunc(int&& x, int& y)
{
x += 10;
y += 10;
cout << "x = " << x << ", y = " << y << endl;
return;
}
int main()
{
int i = 100;
FuncTemplate(myfunc, 20, i);
cout << "i = " << i << endl;
return 0;
}
2.完美转发
在上面代码中,经历了函数模版参数 t
这一次转发,右值的属性被改变为了左值,为了解决上述问题,这时就需要完美转发了。
#include <iostream>
using namespace std;
template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q) // 函数模板,万能引用
{
// f是要转发的目标函数
// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用x接收
// i是左值,Q为int&类型,q为int&类型
f(std::forward<T>(t), q); // forward实现完美转发
}
void myfunc(int&& x, int& y)
{
x += 10;
y += 10;
cout << "x = " << x << ", y = " << y << endl;
return;
}
int main()
{
int i = 100;
FuncTemplate(myfunc, 20, i);
cout << "i = " << i << endl;
return 0;
}
3.std::forward和std::move的区别
#include <iostream>
using namespace std;
void print(int& t) // 形参的类型是左值引用
{
cout << "print(int& t)" << endl;
}
void print(int&& t) // 形参的类型是右值引用
{
cout << "print(int&& t)" << endl;
}
template <typename T>
void FuncTemplate(T&& t) // 函数模板,万能引用
{
// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用接收
print(t);
print(std::forward<T>(t));
print(std::move(t));
}
int main()
{
FuncTemplate(20);
return 0;
}
输出结果如下:
#include <iostream>
using namespace std;
void print(int& t) // 形参的类型是左值引用
{
cout << "print(int& t)" << endl;
}
void print(int&& t) // 形参的类型是右值引用
{
cout << "print(int&& t)" << endl;
}
template <typename T>
void FuncTemplate(T&& t) // 函数模板,万能引用
{
// i是左值,T为int&类型,t为int&类型
print(t);
print(std::forward<T>(t));
print(std::move(t));
}
int main()
{
int i = 100;
FuncTemplate(i);
return 0;
}
输出结果如下: