Template function
Generic programming
How to implement a universal exchange function?
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
void Swap(double& left, double& right)
{
double temp = left;
left = right;
right = temp;
}
void Swap(char& left, char& right)
{
char temp = left;
left = right;
right = temp;
}
......
Although function overloading can be achieved, there are a few disadvantages:
-
Overloaded functions are only different types, the code reuse rate is relatively low, as long as there are new types, you need to add corresponding functions
-
The maintainability of the code is relatively low, one error may cause all overloads to go wrong
Can you tell the compiler a model and let the compiler use the model to generate code according to different types ?
In fact, in C ++, there is such a mold , by filling the mold with different types , to generate different specific types of code .
Generic programming: writing generic code independent of type is a means of code reuse. Templates are the foundation of generic programming.
Function template
Function template concept
A function template represents a family of functions. The function template has nothing to do with the type. It is parameterized when used, and a specific type version of the function is generated according to the actual parameter type.
Function template format
Code example:
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表)
{
}
template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
Note: typename is used to define template parameter keywords , you can also use class (remember: you can not use struct instead of class)
Principles of function templates
A template is a blueprint. It is not a function in itself. It is a mold that the compiler uses to generate a specific type of function. So in fact, the template is to hand over the repetitive things that we should do to the compiler.
At the compiler compilation stage , for the use of template functions, the compiler needs to derive the corresponding type of function for the call based on the incoming argument type . For example, when using a function template with a double type, the compiler determines T as a double type by deducing the actual parameter type , and then generates a code that specifically handles the double type , as does the character type.
Function template instantiation
When a function template is used with different types of parameters , it is called instantiation of the function template . Template parameter instantiation is divided into: implicit instantiation and explicit instantiation.
- Implicit instantiation: let the compiler infer the actual type of template parameters based on the actual parameters
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main() {
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2);
//该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型
//通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,
//编译器无法确定此处到底该将T确定为int 或者 double类型而报错
//注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
//Add(a1, d1);
// 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
Add(a1, (int)d1);
return 0;
}
- Explicit instantiation: Specify the actual type of the template parameter in the <> after the function name
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}
Template parameter matching principle
- A non-template function can coexist with a function template with the same name, and the function template can also be instantiated as this non-template function
// 专门处理int的加法函数
int Add(int left, int right) {
return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right) {
return left + right;
}
void Test() {
Add(1, 2); // 与非模板函数匹配,编译器不需要特化
Add<int>(1, 2); // 调用编译器特化的Add版本
}
- For the non-template function and the function template with the same name, if the other conditions are the same, the non-template function will be called preferentially during the transfer without generating an instance from the template. If the template can produce a function with a better match, then the template will be selected
// 专门处理int的加法函数
int Add(int left, int right) {
return left + right;
}
// 通用加法函数
template<class T1, class T2> T1
Add(T1 left, T2 right)
{
return left + right;
}
void Test() {
Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
Add(1, 2.0);// 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
}
- There is no implicit type conversion in the function template in the process of passing parameters, but ordinary functions can perform implicit type conversion
template <typename T>
void test_fuc(T& t1, T& t2)
{
cout << "template...\n";
}
void test_fuc(int a, char b)
{
cout << "ordinary fuction...\n";
}
int main()
{
int a = 1;
char b = 0;
test_fuc(b, a); //访问普通函数,因为模板函数不能有隐式转化,必须严格匹配,普通函数则不同。
return 0;
}
If you have different opinions, please leave a message to discuss!