Syntax and Principle of Template in c++

Grammar and principles of C++ templates

1. Generic programming

How do I implement a common exchange function?
First method: using function overload to implement

#include<ostream>
void swap(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}
void swap(double& a, double& b)
{
	double temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 1, b = 2;
	swap(a, b);
	double c = 1.1, d = 2.2;
	swap(c,d);
	return 0;
}


Second method: using generic programming
Definition: Writing generic type-independent code is a means of code reuse, and templates are the basis of generic programming.

Format: template<typename T1...>{}
		 Return Value Type Function Name Parameter List {}
Re-implementation using generic programming swap function
template<typename T>
void swap(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
int main()
{
	int a = 1, b = 2;
	swap(a, b);
	double d1,d2;
	swap(d1,d2)
	return 0;
}

2. Function templates

**

1. First Identity Function Template

**
Understanding: Function templates represent a family of functions that are type-independent and are parameterized when used to generate corresponding types based on the type of parameters.
Format:

template <typename T1...>{}
Return value type function name (parameter list){}
A function template is actually a blueprint, not a function in itself, but a stencil for the compiler to use to produce a specific type of function
 So the function template is actually handing over to the compiler what you were doing.

>In the compilation phase, the compiler deduces a function of the corresponding type based on the type of argument passed in for invocation. As shown above, when the int type uses a function template, the compiler determines T as the int type by deducing the actual parameter type, and then generates a code that specifically handles the int type.

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

(1) Implicit instantiation: Let the compiler infer the actual type of template parameter based on arguments

template<typename T>
T add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int i = 10, j = 20;
	add(i, j);
	double a = 10.1, b = 10.2;
	add(a, b);
	add(i, a);//This statement cannot be compiled because the compiler cannot make type inferences
	//Because i is int and a is double, the compiler cannot infer
	//But there are two ways to deal with this situation:
	//1. Make a forced conversion, for example: add(i,(int)a);
	//2. Explicit instantiation
	return 0;
}

(2) Explicit instantiation: specify the actual type of template parameter in <>after the function name

template<typename T>
T add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	int i = 10, j = 20;
	add(i, j);
	double a = 10.1, b = 10.2;
	add(a, b);

	//Explicit instantiation: directly specifying the type
	add<int>(i, j);
	add<double>(a, b);
	add<int>(i, a);
	return 0;
}

(3) Principles for matching template parameters: 1. A non-template function can coexist with a function template of the same name, and the function template can also be instantiated as this non-template function.

//Addition functions that deal specifically with int s
int add(int left, int right)
{
	return left + right;
}

//General Addition Function
template<typename T>
T add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	add(1, 2);//Non-template function matching
	add<int>(1, 2);//Template function matching
	return 0;

2. For non-template functions and function templates with the same name, if all other conditions are the same, non-template functions will be called first instead of an instance from the template function. If a template can produce a function with a better match, select a template

//Addition functions that deal specifically with int s
int add(int left, int right)
{
	return left + right;
}

//General Addition Function
template<typename T>
T add(const T& left, const T& right)
{
	return left + right;
}
int main()
{
	add(1, 2);//Non-template function matching, function template instantiation is not required
	add(1, 2.0);//Function templates can generate more matching versions, and the compiler generates more matching functions based on arguments.
	return 0;

}

3. Template functions do not allow automatic type conversion, but common functions do.

3. Class Templates

Define format:
template <class T1...>
class Class Template Name
{
...//Intra-class member definition
};

(1) Class template instantiation: Class template instantiation is different from function template instantiation. Class template instantiation needs to be followed by <> class template name, and then put the instantiated type in <>. Class template name is not a real class, but the result of instantiation is a real class.
For example: Vector s1; //Instantiate vectors template, int type S1
Vector s2; //Instantiate vectors template, double type S2

template<class T>
class Vector
{
public:
	Vector(int capacity = 10)//Initialize using an initialization list, constructor
		, _pData(new T[capacity])//Use new request space and initialization
		, _size(0)
		, _capacity(capacity);
	~Vector();//Destructors, declared in classes, defined outside classes.
	T& operator[](int pos) //operator[] overload
	{
		assert(pos < _size);
		return _pData[pos];
	}
	//In addition to reading, you can also modify because of the use of &.

private:
	T* _pData;
	int _size;
	int _capacity;

};

//The template does not support declaring.h, defining.cpp, and detaching compilation.
template <class T>
Vector<T> ::~Vector()
{
	if (_pData)
	{
		delete[] _pData;
	}
	_size = _capacity = 0;
}

Keywords: C++

Added by Dan911 on Wed, 29 Sep 2021 19:52:07 +0300