Understand templates in one article

Background introduction:
Imagine that we want to implement a function for adding integers and floating point numbers. If we follow the C language, we need to write two functions with different function names to complete the addition; if using C++ language, we can Through the feature of function overloading, you can write two functions with the same function name but different parameter lists to complete the task.
No matter what, we need to implement two functions?

So can we just write a general function to complete this task?
Next, we need to invite the template to appear!

1. Template concept

Function templates represent a family of functions that are type-independent and are parameterized when used, producing characteristic type versions of the functions based on the actual parameter types.

2. How to use

Use the following method to define a function template, and you can define multiple template parameters as needed.
template<class A, class B…>

template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}

3. Template principle

In the compiler compilation phase, for the use of function templates, the compiler needs to deduce and generate corresponding types of functions for calling based on the passed in actual parameter types .
For example: when using a double type and a function template, the compiler will automatically generate a double type function for calling by deducing the actual parameters.
Insert image description here


template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}


int main()
{
    
    

	int a = 10;
	int b = 11;

	double c = 1.1;
	double d = 2.2;

	Add(a, b);
	Add(c, d);
	return 0;
}

Insert image description here

As can be seen from the above example, the compiler does automatically generate two functions with different parameters (because the calling addresses are different).

4. Template instantiation

When a function template is used with parameters of different types, it is called instantiation of the function template. Template parameter instantiation is divided into: implicit instantiation and explicit instantiation.

4.1 Implicit instantiation

Let the compiler deduce it by itself based on the actual parameter type.

template<class T>    //template<typename T>   也可以
T Add(T x, T y)
{
    
    
	return x + y;
}


int main()
{
    
    

	int a = 10;
	int b = 11;

	double c = 1.1;
	double d = 2.2;

	Add(a, b);  // 生成整形模板
	Add(c, d);   //生成double模板
	Add(a, d);   // 编译报错,因为a是int,b是double,只有一个模板T,编译器不知道生成哪个。
	// 解决方法:
	//1.用户自己来强制转化
	Add(a, (int)d);
	//2. 使用显示实例化
	return 0;
}

4.2 Explicit instantiation

Specify the actual type of the template parameter in <> after the function name.

int a = 10;
double b =1.1;
Add<int>(a, b);   //显示实例化
// 如果类型不配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器会自动报错。

5. Template parameter matching rules

  1. A non-template parameter can exist simultaneously with a function template of the same name, and the function template can also be instantiated as the 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版本
}
  1. For non-template functions and function templates with the same name, if all other conditions are equal, the non-template function will be called in preference to an instance specializing from the template; if the template can produce a more suitable function, 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函
}
  1. Template functions do not allow automatic type conversion, but ordinary functions can perform automatic type conversion.

6. Class template

6.1 Define format

Class templates are not real classes, but the result of instantiation is the real class.

template<class T1, class T2, ..., class Tn>
class A
{
    
    
 // 类内成员定义
};

Instantiate an object of type A, the type requirement is int.

A<int> a;
// A 类名,A<int> 才是类型

Guess you like

Origin blog.csdn.net/weixin_45153969/article/details/132914542