So many of the names are actually three kinds.
1. Display instantiation
2. Implicit instantiation
3. Specialization (= materialized), partial specialization
First, the instantiation of
1. Display, implicit instantiation
What is instantiation: the process of replacing a template parameter with a specific value, generating a normal class, function, or member function from a template.
Display instantiation: Visible by name, which clearly indicates the type you want to instantiate
Implicit instantiation: Determine the type to instantiate by the compiler's own assumptions.
For example, a template:
Template<class t>//function template implementation
void Swap (t &a, T &b)
{
T temp;
temp = A;
A = b;
b = temp;
}
A. Display instantiation
template void swap<int> (); There is no need to rewrite the function body for this function, this is just a declaration
Why should I display instantiation?
Primarily to improve efficiency, when you explicitly instantiate a template, the compiler generates a template instance based on the specified type of explicit instantiation before using the template, which is equivalent to one of the functions in this program:
void swap (int &a, int &b)
{
int temp;
temp = A;
A = b;
b = temp;
}
That way, each time you need to call Swap<int> (A, B), you can save space and improve efficiency by regenerating that type of code each of these times. This is why the explicit instantiation occurs.
B. Implicit instantiation
Implicit instantiation refers to the compiler not generating declarations and defining instances of a template until the template is used. The compiler generates instances of the appropriate type based on the template definition only when the template is used.
int i=0, j=1;
Swap (I, j); The compiler implicitly generates a function definition for swap<int> (int &a, int &b) based on the type of the parameter i,j.
Implicit instantiation is the programmer for the sake of convenience, the type omitted to let the compiler judge, this is a lazy performance bar.
Second, special
1. Specialization (= materialized)
However, there are usually some special cases, can not directly use the generic template deployment implementation, it is necessary for a particular type or a particular class of type, and implement a special case template ———— that template specialization.
When T is a struct type, it cannot be exchanged, so we specifically write a function for this particular case, and only call this special function if T is the struct type.
to the function
#define MAXNAME 128
struct job
{
Char Name[maxname]:
int salary;
};
Template<class t>
void Swap (t &a, T &b)
{
T temp;
temp = A;
A = b;
b = temp;
};
template void swap<int> (int &a, int & B); Explicit instantiation, simply declare
template<> void swap<job> (Job &a, Job &b)//explicit materialization (as already mentioned above, note separated from instantiation, must be defined)
{
int Salary:
Salary = A.salary:
A.salary = b.salary;
B.salary = salary;
};//explicite Specialization.
For a class template:
Template <class t>
Class Arrary
{
Private
t* ar;
int l;
...
};//template class declaration.
Template class array<int>; Explicit instantiation. Explicit instantiation
Template<> class Array<job>
{
Private
Job* ar;
int l;
};//expicit Specialization. Explicit materialization, the class definition body can be different from the class template array
2. Partial localization
The template's partial specificity refers to the need to be specific to some parameters of the template.
A. Partial specificity of class templates
For example, the definition of a class vector in the C + + standard library
Template <class T, class allocator>
Class Vector {//...//};
Template <class allocator>
Class Vector<bool, allocator> {//...//};
In this biased example, one parameter is bound to the bool type, and the other parameter is still specified by the user when it is used.
B. Partial specificity of function templates
It is said on the Internet that the function template does not support bias in the strict sense (I do not understand this very well), but because the function can be overloaded, it can be achieved similar to the effect of class template biasing.
Like what:
A) template <class t> void f (T);
Overloading a) According to the overloaded rules
b) template < class t> void F (t*);
If a is called a base template, then B) is called an overload of base template A, not a).
Here I do not delve into the analysis of the special.
Third, the matching order of the template
1. Matching rules for class templates
For example:
Template <class t> class vector{//...//}; (a) General type
Template class vector<typename>; Explicit instantiation of (b)
Template <class t> class vector<t*>{//...//}; (c) Specificity of pointer types
Template <> class vector <void*>{//...//}; (d) void* of the Special
Each type can be used as an argument to the normal type (a), but only the pointer type can be used as a parameter of (b), and only void* can be a parameter of (c)
So, when a template class is called, first, the explicit instantiation is found, if it does not match; then, to find the special, then, to find the special, and finally, according to the template implicit instantiation
2. Matching rules for function templates
For example:
void swap (int &a, int &b) {}//normal function
template<> swap<int> (int &a, int &b) {}//special template function
template void swap<int> (int &a, int &b); Explicit instantiation, this is only a declaration of the line
Template<class t> void Swap (t &a, T &b) {}//Template
The order in which these are written is the order in which the templates are called.
Detailed analysis of template explicit, implicit instantiation and (partial) specialization, materialization (RPM)