Templates first acquaintance

Templates are the basis for the realization of generic programming . Generic programming refers to writing logic codes that have nothing to do with types, and is a means to achieve reuse.

Templates can be divided into: function templates, class templates

Function template

concept

The 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 type of the actual parameter.

Function template format

template<typename T1,typename T2,……,typename Tn>
返回值类型 函数名(形参列表){
    
    函数体}

Such as:

template<typename T>
void Swap(T& left,T& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}//一个可以实现交换功能的函数模板

[Note]: typename Can also be used classinstead

The principle of function template

A function template is a mold for the compiler to generate a specific specific type of function, not a function itself !

During the compilation phase of the compiler, when a function template needs to be used to generate a function of a specific type, the compiler will determine the incoming type T through the deduction of the actual parameter types , and then generate a function that specializes in processing the T type.

Such as:

double a = 3.14, b = 6.28;
int  x = 1,y = 2;
char r = 'a', t = 'v';
Swap(a,b);
Swap(x,y);
Swap(r,t);

Because Swapof the function template in the code, different types of data are passed in the three calls, and the compiler infers the type of each incoming data at the stage, and generates respective corresponding functions .

The above code will have 3 more functions in the compilation stage:

void Swap(double& left,double& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}
void Swap(int& left,int& right){
    
    
	int tmp = left;
	left = right;
	right = tmp; 
}
void Swap(char& left,char& right){
    
    
	char tmp = left;
	left = right;
	right = tmp; 
}

These three functions correspond to three calls of the Swap function respectively . We only wrote a function template, but in the final code, different types of actual parameters will be passed in, resulting in many more functions. In other words, the code that uses the template has the problem of code bloat.

However, I think that we don't need function templates to achieve the same functions for different types of data. It seems that we can only implement functions through function overloading , and we still have to write a lot of functions. The use of templates frees developers from repeatedly writing functions of the same function and different types, which reduces to a certain extent the inefficient but inevitable work content that is of little significance to developers, and improves work efficiency. Even if the code that uses templates has bloat problems, it seems that it will only bloat to the point where templates are not used. This is not an unacceptable problem.

Instantiation of function templates

The process by which the compiler infers the types of incoming arguments and generates corresponding functions for different types is called the instantiation of function templates. Template instantiation can be divided into: implicit instantiation and explicit instantiation

Implicit instantiation

Implicit instantiation means that the developer does not tell the compiler the type of the argument passed in, and lets the compiler deduce what kind of function it should generate based on the type of the argument passed in . As follows, we do not tell the compiler what type of argument is passed in.

template<typename T>
void Swap(T& left,T& right){
    
    
	T tmp = left;
	left = right;
	right = tmp; 
}//一个可以实现交换功能的函数模板

int main(){
    
    
	double a = 3.14, b = 6.28;
	Swap(a,b);//隐式实例化
	return 0;
}

Explicit instantiation

To display the instantiation, we only need to <>fill in the actual parameter type in the function name,
such as:

	Swap<double>(a,b);//显式实例化

I personally feel that we should use explicit instantiation when using function templates, so that we can grasp our own code and make it easier for others to read.

Matching principle of template parameters

Generally speaking, when both non-template functions and template functions that can complete a function exist, there is a strategy to help the compiler decide which way to define the function.

In the vernacular, there are many kinds of functions that can complete the specified function. Some function compilers in this pile of functions do not need to do anything. It exactly matches the parameter list of the called function; some require implicit type conversion; Some have type conversions specified by the developer. At this time, if you want to complete a function, you have many options. In order to avoid errors in the result and avoid the compiler from jumping left and right, there is a selection strategy to help the compiler choose the function to be called.

The adjustment selection strategy is as follows (the priority is arranged from high to bottom):
1. Complete match: function template and non-template function exist at the same time and both can complete the specified function, and the type does not conflict (the use of non-template function is preferred )
2. Upgrade conversion ( charWith shortautomatic conversion int, flaotautomatic conversion to double)
3. Standard conversion ( intto char, longto transfer double)
4. User-defined conversion, such as the conversion defined in the class declaration

Limitations of templates

Suppose there are the following template functions:

template<typename T>
void f(T a,T b){
    
    
	//函数体
}

Generally speaking, there will be some operations in the function.
Such as:

a = b

If Ta built-in data type, this assignment will be in line with our expectations.
But Tto be an array / string / non-built type of structure and so on, the result most likely not meet our expectations.

Another example:

if(a>b)

If Tis an array, a>bthe array comparison awith bthe address level, this is probably not what we want.

In short, template functions may not be able to handle certain types.
We need to remember that everything has two sides! There is nothing absolutely good, and nothing absolutely bad.

Class template

Class template format

template<class T1,class T2,……,class Tn>
class 类模板名
{
    
    
	//类内成员定义
}

[Note] When the members of the class in the class template are defined outside the class, the template parameter list needs to be added

Instantiation of class template

Different from the function template instantiation, the class template instantiation needs to be added after the class template name <>, and then the instantiated type is put in <>. That is, it must be explicitly instantiated.

The same explanation applies to class templates: class templates are not classes! The instantiation result of the class template is the class!

Guess you like

Origin blog.csdn.net/qq_39208237/article/details/115342214