C + + template function

Posted by cool75 on Wed, 08 Dec 2021 12:11:43 +0100

1. Template function

1. Declaration and definition of template function

C + + provides the concept of template programming. The so-called template is actually to establish a general function or class. The type inside the class and the formal parameter type of the function are not specified specifically, but are represented by a virtual type. This common approach is called template. Templates are the foundation of generic programming, which is writing code in a way independent of any particular type.

In short, we provide an abstract function, which does not specify the data type, but a virtual type instead. Only basic functions are provided. Its specific data type is instantiated only when it is called.

That may still be very abstract. It's easy to understand by taking an example.

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T2 test(T1 tmp, T2 tmp1) {

	T2 tmp2 = tmp + tmp1;

	return tmp2;
}

int main(void) {

	cout << "test(10, 5)=" << test(10, 5) << endl;     //The template function is called, and the template function automatically deduces the non instantiated type through the passed in parameters
	cout << "test(5,'A')=" << test(5,'A') << endl;
	cout << "test(10.5, 5.5) =" << test(10.5, 5.5) << endl;

	system("pause");

	return 0;
}

The output result is:

The declaration of the function template is implemented through the keywords template and typename. Template tells the compiler that this is the declaration of the function template, and typename is used to declare the virtual type. For example, if you want to declare a template function that requires two different variables, you need to declare two different virtual types T1 and T2 through typename.

After declaration, you can use virtual types to define variables in the function definition, but note that variables defined with the same virtual type can only be of the same type. For example, variables defined with T1 can only be of the same type, either int or char. This depends on which type it is instantiated to when instantiated.

2. Calling of template function

Explicit type call

The template function can be called explicitly, that is, the specific type of virtual type can be indicated artificially when calling.

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T2 test(T1 tmp, T2 tmp1) {

	T2 tmp2 = tmp + tmp1;

	return tmp2;
}

int main(void) {

	cout << "test(5,'A')=" << test<int,char>(5, 'A') << endl;          //< int, char > explicitly indicates the type of template

	system("pause");

	return 0;
}

Automatic derivation

That is, it does not specify the specific data type, but allows the compiler to automatically deduce the data type according to the incoming data.

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T2 test(T1 tmp, T2 tmp1) {

	T2 tmp2 = tmp + tmp1;

	return tmp2;
}

int main(void) {

	cout << "test(5,'A')=" << test(5, 'A') << endl;          //Automatically derive data types

	system("pause");

	return 0;
}

3. Bottom implementation of template function

After the template function is instantiated, it will be replaced by a specific function. For example, a version of code has a template function. After it is called, the virtual type is automatically derived as int. After compilation, functions instantiated as int (i.e. ordinary functions with all virtual types replaced by int) will be generated without calling the template function, that is, when calling, the template function will be replaced by functions instantiated as ordinary functions.

From this, we may know whether it is automatic derivation or explicit type assignment. Virtual types that cannot be known by the compiler are not allowed. More specifically, when using automatic derivation to derive template function types, the compiler must be able to derive specific types.

Look at an example that cannot be deduced by the compiler.

Error code:

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T1 test(T1 tmp, T1 tmp1) {

	T2 tmp2;               //T2 cannot be derived from a specific type                     

	return (tmp + tmp1);
}

int main(void) {

	cout << "test(5, 6)=" << test(5, 6) << endl;        

	system("pause");

	return 0;
}

4. Template function and function overloading

People who are familiar with function overloading should be curious. If there are both template functions and common functions of the same name, and the number of parameters in the parameter list is the same, then which function does the compiler invoke in the main function to call the same name function?

Here is an example:

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T1 test(T1 tmp, T2 tmp1) {

	cout << "Call template function!" << endl;

	return (tmp + tmp1);
}

int test(int tmp, int tmp1) {                  //Overloaded normal functions

	cout << "Call ordinary function!" << endl;

	return 0;
}

int main(void) {

	char tmp = 'c';
	int tmp1 = 0;
	int a = 5;

	cout << "test(5,'c')=" << test(a, tmp) << endl;     
	cout << "test(5,0)=" << test(a, tmp1) << endl;

	system("pause");

	return 0;
}

The result is:

The two parameters of an ordinary function are of type int. when test is called for the first time, the second parameter is of type char, which calls the template function, and the second parameter is of type int, which calls the ordinary function.

Why? In theory, both template functions can be matched and used. Ordinary functions can also match the parameters of these two calls (in C language, char variables can be used as int parameters).

This is because the template function can automatically derive types. In the first call, the two types are derived as int and char respectively. Ordinary functions are two int types. Although the passed in parameters can also be used, the template function can obviously better match the parameter list.

In other words, if the instantiated type of the template function can better match the parameter list, the template function will be used.

So what happens when both functions can exactly match the parameter list? It is not difficult to find the result of the second test call. At this time, the compiler will call ordinary functions.

If you must use template functions, you can use < > to explicitly specify the use of template functions. Look at the example below.

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T1,typename T2>             //Template function declaration and definition
T1 test(T1 tmp, T2 tmp1) {

	cout << "Call template function!" << endl;

	return (tmp + tmp1);
}

int test(int tmp, int tmp1) {                  //Overloaded normal functions

	cout << "Call ordinary function!" << endl;

	return 0;
}

int main(void) {

	char tmp = 'c';
	int tmp1 = 0;
	int a = 5;

	cout << "test(5,'A')=" << test(a, tmp) << endl;     
	cout << "test<>(5,0)=" << test<>(a, tmp1) << endl;       //Use < > to explicitly call template functions

	system("pause");

	return 0;
}

2. Below

In the next article, we introduce class templates.

Link:

Topics: C++ Back-end STL