Summary of some knowledge about C++ templates

Templates are a form of static polymorphism. Of course, there is another kind of function overloading, which is mainly reflected by the number, type, and order of parameters. An interface implements different functions.
Note on overloading: the return value cannot be used as a basis, const is added after the member function to form an overload, and const is modified by the this pointer, which means that the function cannot modify the member variable. If the parameter is modified by const, if it is a formal parameter, it does not constitute overloading, because only a value is copied into it, which cannot reflect const. If it is a pointer reference type, it constitutes overloading.

The defect of overloading: If you want to define different add methods, you need to define many add functions with different parameters, which is troublesome. It is more convenient to use templates.
template add(T a,T b) only needs one. You can find that there are many libraries such as STL, BOOST, etc. Templates can be found everywhere, so it is very important to understand it.

Function templates and class templates
template
void swap1(T &a,T &b)
{ T t=a; a=b; b=t; } template is to tell the compiler that I want to be generic, so don't report an error casually (it will search and match ). The call is swap1(1,2); when ordinary functions and template functions exist at the same time, the compiler will limitedly match ordinary functions, and no longer match templates. (Where priority full specialization is greater than partial specialization than generalization) Ordinary functions are first-class citizens, followed by overloading, and then templates. Like class templates, member functions are denoted by T. But class templates have a unique feature of non-type parameters. For example array<int,15> arr. 15 represents size parameters, that is, non-type parameters, which are more generalized than function templates.







Full specialization, partial specialization (function templates cannot be partial specialization).
When certain types need special treatment, full specialization is required. (For example, itertor needs to allow the use of pointers instead of iterable objects, so it needs to be specialized.)
template<> swap(int num1, double num2) is fully specialized, and <> is empty.
There are two forms of partial specialization, one is that some specializations and some remain unchanged. One is to add some restrictions such as const, &, *, etc.
Note: Function templates cannot be partially specialized but only fully specialized. The reason is that overloading can realize the function of partial specialization of functions, so in fact, it is only the compiler that says no. In fact, full specialization will not participate in the resolution of function overloading. So technically it is possible, but the compiler does not allow it to reduce unnecessary burden.

The compilation process of the template (why the template declaration definition must be placed in .h) The
organization process of templates and ordinary functions is different, so you need to pay attention.
Templates are compiled in two phases. The first stage is the template definition stage, this stage will not check the type parameters, such as wrong writing, using symbols that do not depend on template parameters, etc. The second is the template instantiation phase, which checks the type parameters.
It leads to a problem that the declaration and definition of templates cannot be like ordinary functions, where the declaration is placed in the header file and the definition is placed in the source file. Why? Because of the principle of C++ separate compilation .

C++ adopts separate compilation, which has the advantage of avoiding multiple compilations of header files when one source file calls another source file. So separate compilation, each source file is compiled separately, and then linked with definitions in other files when linking.

But the template is not good, we must have such a concept, before the template is instantiated, it is a template, not any variable type. This will cause template functions in other files to not have specific implementations, will not be compiled into specific codes, will not be able to enter the symbol table, and will not be found when linking.

There are three ways to solve this problem.
One is the inclusion mode, which is commonly used to write template definitions and declarations together. the mainstream way. The disadvantage is that if the template is complex, the compilation time is very long.
The second is to display the definition method, add template func() in front of the function. The disadvantage is that if you have a different type, you have to redefine it.
The third is to add the export keyword, but it seems that some compilers do not support it, such as VS.

Guess you like

Origin blog.csdn.net/weixin_53344209/article/details/132282657