Detailed explanation of "C++" template


Template introduction

If you now need to implement a function that exchanges integers, it is easy to implement, but if the exchange type is not mentioned, then you may need to write various types of overloads. Although function overloading can be implemented, it is very troublesome to do so. The usability is very low, and the maintainability of the code is relatively low, an error may make all overloads wrong.

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; 
}
//、、、、、、、、、、出现一个新类型就要添加一个

So how to solve this problem? At this time we can introduce the concept of templates


Basic Concepts of Templates

Before understanding templates, let’s first understand the concept of generic programming. Generic programming refers to writing generic code that has nothing to do with types. It is a means of code reuse. Templates are the foundation of generic programming.

What is a template?

So what is a template?

  • A template is a tool for parameterizing types.
  • A template is a feature of C++ that allows functions or classes (objects) to be expressed or run in the form of generics.
  • Templates can make functions or classes work properly when corresponding to different types, without having to write a code for each type.
  • Templates are the basis of generic programming and are highly reusable
  • The template is a feature of the universal language, and the template is also called parameterized type

The template is like our actual mold. Nothing will be produced without using this mold. Only when you pour in raw materials will you produce something, and when you pour in plastic materials, a plastic model will be produced. Entering molten metal will produce a metal model.
Returning to the question of the introduction, we use templates to be able to write type-independent code. If you don't use a template, then you need to write different types of functions to complete the function overloading to solve the problem in the introduction, but if you use a template, you only need to write a swap template function to implement different types of swap functions.


Template classification

Templates usually have two forms: function templates and class templates

Function template

Function template concept

What is a function template? The function template actually represents a family of functions and establishes a general function. The types used in this function, including parameter types, return value types, and local variable types, can be unspecified. They are only used when they are used. Will be parameterized, and a specific version of the function is generated based on the type of the actual parameter.
Function templates are for functions that differ only in parameter types

How to use function templates

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

Both typename and Class are keywords used to define template parameters, and there is no difference between the two.
Take the swap function of the introduction as an example, use a function template to write a template function of swap:

template<Class T>
//template<typename T> 也可以
void swap(T& left,T& right)
{
    
    
	T temp = left;
	left = right;
	right = temp;
}

When we call this swap template function, the type T will be replaced by the type at the time of the call. For example, swap(a,b), both parameters are of type int, then T will be replaced with int Type, the template function is replaced with swap(int& a, int& b).

It should be noted that the declaration or definition of the template can only be done in the global, namespace or class scope. That is, it cannot be performed in a local scope, within a function, for example, a template cannot be declared or defined in the main function.

Function template instantiation

In fact, the template function is not a real function. During the compilation phase, when the compiler calls the function template, the compiler will deduce the type of the template based on the type of the actual parameter, and then generate a specific type of function.
Insert picture description hereThe use of function templates with different types of parameters is called the instantiation of function templates. The instantiation of template type parameters is divided into: implicit instantiation, explicit instantiation
1. Implicit instantiation: let the compiler deduce the actual type of the template parameter 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);

	return 0;
} 

But if you want to compile the following code, you will get an error, because during the compilation phase, when the compiler deduces the actual parameter type, it deduces T to int type through a1, but deduces T to double type through b1, but the template parameter There is only one T in the list. At this time, the compiler cannot determine which type to use to replace T, and an error is reported. (The compiler generally does not perform type conversion operations)

template<class T> 
T Add(const T& left, const T& right) 
{
    
        
	return left + right; 
}
 
int main() 
{
    
        
	int a1 = 10;    
	double b1 = 10.0;   
	Add(a1, b1);    

	return 0;
} 

So how to solve this problem? There are two ways to deal with the
first method, the user casts the type by himself

int main() 
{
    
        
	int a1 = 10;    
	double b1 = 10.0;   
	Add(a1, (int)b1); //强制把b1转为int类型   

	return 0;
} 

The second method is to use explicit instantiation
2. Explicit instantiation: specify the actual type of the parameter in <>
or take the above code as an example

int main() 
{
    
        
	int a1 = 10;    
	double b1 = 10.0;   
	Add<int>(a1, b1);  //显式实例化  

	return 0;
} 

Matching principle of function parameters

Look at this code first

// 加法模板函数 
template<class T> 
T Add(T left, T right) 
{
    
        
	return left + right; 
}
 
 // 专门处理int的加法函数 
 int Add(int left, int right) 
 {
    
        
 	return left + right; 
 }
 
 void Test() 
{
    
        
		Add(1, 2);// 与非模板函数匹配,编译器不需要特化    	
		Add<int>(1, 2);  //调用编译器特化的Add版本 
}

We know that the Add template function will instantiate an int type Add function code when it encounters an int type actual parameter, so can the int type Add function and the Add function template in the above code exist at the same time?
Can exist at the same time, and the function template can also be instantiated as this non-template function.
In Test(), when Add(1,2) calls the Add function, because there is already an Add function of type int, it must be faster to directly call the Add function of processing int type, because the template function has to be deduced. After the parameter type, a specific code for processing the int type is generated. But if I force the use of a template function, then use Add(1,2) to call the Add version after the function template is instantiated.

Class template

Basic concepts of class templates

In addition to supporting function templates, C++ also supports Class Templates. Type parameters defined in function templates can be used in function declarations and function definitions, and type parameters defined in class templates can be used in class declarations and class implementations. The purpose of the class template is also to parameterize the type of data.
Class templates are for classes that differ only in data members and member function types.

How to use class templates

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

Once the class template is declared, formal parameter names (T1, T2...Tn) can be used to declare member variables and member functions in the class, for example:

template<Class T>
class A
{
    
    
public:
	T a;
	T b;
	T c(T d,T& e);
};

Class template instantiation

The instantiation of a class template is different from the instantiation of a function template. The instantiation of a class template needs to follow the name of the class template with <instance type>. It should be noted that there is no deduction in the class template, such as A<2> s. An error will be reported, and the compiler cannot deduce 2 as an int type. You must specify the type explicitly in <>.
Using the above code as an example, we instantiate an A< int> m, then all the use of template parameters in class A will be replaced by int:

class A
{
    
    
public:
	int a;
	int b;
	int c(int d,int& e);
};

Guess you like

Origin blog.csdn.net/NanlinW/article/details/109709793