完美转发和可变参数模板
(1)完美转发
A.What(什么是完美转发)
某些函数将其一个或多个实参连同其类型不变地转发给其它函数,我们需要保证被转发实参的所有性质,这种保证转发实参所有性质的参数传递,我们称之为“完美转发”
B.How(如何进行完美转发)
常见的模板函数定义形式如下:一般使用两个引用符来实现完美转发
template <typename F, typename T1, typename T2>
auto flip(F f, T1 &&t1, T2 &&t2)
{return f(t1, t2);
}
假如存在函数func()如下:
int func(int& iVal01, int iVal02)
{return iVal01 + iVal02;
}
int main()
{int iVal = 10;auto res = flip(func, iVal, 30); //res为40return 1;
}
在上述例子中,T1为int& &&,折叠为int& t1,从而实现了完美转发
C. forward()和move()函数介绍
forward() 可以保持给定实参的左值/右值属性
forward<T>(t); //使用方式,保持t的左值或右值属性
move函数将左值转换为右值
std::string str = "Hello, ThreeBody!";
std::string &&ref = std::move(str); //将左值强转为右值
(2)可变参数模板
A.What(什么是可变参数模板)
模板参数的长度可变,以递归的形式来访问传入的参数
void show() // 终止条件
{ cout << endl;
}
template <typename T, typename... Args> // Args 为模板参数包,表示 0 个或多个模板参数
void show(const T &t, const Args &...args) // args 为函数参数包,表示 0 个或多个函数参数
{cout << t << " " << endl; cout << sizeof...(Args) << endl; // 2 1 0 ;sizeof...运算符,返回包中参数的个数 cout << sizeof...(args) << endl; // 2 1 0show(args...);
}
string zs = "张三";
double defict = 128.1;
int year = 1981;
show(zs, defict, year);
B.包拓展
包拓展就是将可变参数模板分解成构成元素
C.转发参数包
实现可变参数的“完美转发”
void show() // 终止条件
{cout << endl;
}
template <typename T, typename... Args> // Args 为模板参数包,表示 0 个或多个模板参数
void show(T &&t, Args &&...args) // args 为函数参数包,表示 0 个或多个函数参数
{cout << t << " " << endl; cout << sizeof...(Args) << endl; cout << sizeof...(args) << endl; show(std::forward<Args>(args)...);
}