First, function template
1. Definition
Template <class type parameter 1,class type parameter 2,...... >
Return value type template name (formal parameter list) {
function body
};
template <class T1, class T2>
T2 print(T1 arg1, T2 arg2)
{
cout<< arg1 << " "<< arg2<<endl;
return arg2;
}
2. Do not instantiate function template by parameter
#include <iostream>
Using namespace std;
Template <class T>
T Inc(T n){
Return 1 + n;
}
Int main(){
Cout << Inc<double>(4)/2; //output 2.5
Return 0;
}
3, function templates can be overloaded, as long as their formal parameter list or type argument table is different
template<class T1, class T2>
void print(T1 arg1, T2 arg2) {
cout<< arg1 << " "<< arg2<<endl;
}
template<class T>
void print(T arg1, T arg2) {
cout<< arg1 << " "<< arg2<<endl;
}
template<class T,class T2>
void print(T arg1, T arg2) {
cout<< arg1 << " "<< arg2<<endl;
}
4. Order of function templates and functions
In cases where multiple functions and function templates have the same name, the compiler processes a function call statement as follows
-
Find the normal function (a function that is not instantiated by the template) that exactly matches the parameters.
-
Then find the template function that exactly matches the parameters.
-
Then find the normal function that can be matched after the automatic type conversion of the real parameter.
-
The above can not be found, the error.
Template <class T>
T Max( T a, T b) {
Cout << "TemplateMax" <<endl; return 0;
}
Template <class T,class T2>
T Max( T a, T2 b) {
Cout << "TemplateMax2" <<endl; return 0;
}
Double Max(double a, double b){
Cout << "MyMax" << endl; return 0;
}
Int main() {
Max( 1.2, 3.4); // output MyMax
Max(4, 5); //output TemplateMax
Max( 1.2, 3); //Output TemplateMax2
Return 0;
}
5. No type auto-conversion when matching template functions
template<class T>
T myFunction( T arg1, T arg2)
{ cout<<arg1<<" "<<arg2<<"\n"; return arg1;}
……
myFunction( 5, 7); //ok :replace T with int
myFunction( 5.8, 8.4); //ok: : replace T with double
myFunction( 5, 8.4); //error ,no matching function for callto 'myFunction(int, double)'
Second, class template
1. Definition
When defining a class, add one/more type parameters. When you use a class template, you specify how the type parameter should be substituted for the specific type, and the compiler generates the corresponding template class accordingly.
Template <class type parameter 1,class type parameter 2,......>//type parameter table
Class template Name {
member functions and member variables
};
(1) The notation of member functions in a class template:
Template <class type parameter 1,class type parameter 2,......>//type parameter table
return value type class template name < type parameter name list;:: member function names (parameter table) {
......
}
(2) Define the object's wording with a class template:
Class template name < real type parameter table > object name (constructor argument list);
// Pair class template
Template <class T1,class T2>
Class Pair{
Public:
T1 key; //keyword
T2 value; //value
Pair(T1 k,T2 v):key(k),value(v) { };
Bool operator < ( const Pair<T1,T2> & p) const;
};
Template<class T1,class T2>
Bool Pair<T1,T2>::operator < ( const Pair<T1,T2> & p) const{ //Pair member function operator <
Return key < p.key;
}
Int main(){
Pair<string,int> student("Tom",19); //Instantiate a class Pair<string,int>
Cout << student.key << " " << student.value;
Return 0;
}
/ / Output:
Tom 19
2. Defining objects with Class templates
-
The process by which a compiler generates a class from a class template is called a instantiation of a class template. Classes that are instantiated by class templates are called template classes.
-
The two template classes of the same class template are incompatible.
3. function templates as class template members
Template <class T>
Class A{
Public:
Template<class T2>
Void Func( T2 t) { cout << t; } // member function template
};
4. Class template and non-type parameter: Non-type parameter can appear in "< type parameter table >" of class Template
Template <class T, int size>
Class CArray{
T array[size];
Public:
Void Print(){
For( int i = 0;i < size; ++i)
Cout << array[i] << endl;
}
};
CArray<double,40> a2;
CArray<int,50> a3; //a2 and a3 belong to different classes
5. Class template and derivation
(1) Class templates derive from class templates
template <class T1,class T2> int main() {
class A { B<int,double> obj1;
T1 v1; T2 v2; C<int> obj2;
}; return 0;
template <class T1,class T2> }
class B:public A<T2,T1> { class B<int,double>:
T1 v3; T2 v4; public A<double,int>{
}; int v3; double v4;
template <class T> };
class C:public B<T,T> {
T v5;
};
(2) class template derived from template class
Template <class T1,class T2>
Class A {
T1 v1; T2 v2;
};
Template <class T>
Class B:public A<int,double> {
T v;
};
Int main() {
B<char> obj1; //Automatically generate two template classes: A<int,double> and B<char>
Return 0;
}
(3) class template derived from normal class
Class A {
Int v1;
};
Template <class T>
Class B: public A { //All classes obtained from B instantiation, all based on A
T v;
};
Int main() {
B<char> obj1;
Return 0;
}
(4) Normal class derives from template class
template <class T>
class A {
T v1;
int n;
};
class B:public A<int> {
double v;
};
int main() {
B obj1;
return 0;
}
6. Class template and friend function
(1) member functions of functions, classes, and classes as Friends of class templates
Void Func1() { }
Class A { };
Class B{
Public:
Void Func() { }
};
Template <class T>
Class Tmpl{
Friend void Func1();
Friend class A;
Friend void B::Func();
}; / / Any class instantiated from Tmp1, there are three friends above
(2) function template as Friend of class template
#include <iostream>
#include <string>
Using namespace std;
Template <class T1,class T2>
Class Pair{
Private:
T1 key; //keyword
T2 value; //value
Public:
Pair(T1 k,T2 v):key(k),value(v) { };
Bool operator < ( const Pair<T1,T2> & p) const;
Template <class T3,class T4>
Friend ostream & operator<< ( ostream & o,const Pair<T3,T4> & p);
};
Template <class T1,class T2>
Bool Pair<T1,T2>::operator < ( const Pair<T1,T2> & p) const{ //"small" means small keyword
Return key < p.key;
}
Template <class T1,class T2>
Ostream & operator<< (ostream & o,const Pair<T1,T2> & p){
o << "(" << p.key << "," << p.value << ")" ;
Return o;
}
Int main()
{
Pair<string,int> student("Tom",29);
Pair<int,double> obj(12,3.14);
Cout << student << " " << obj;
Return 0;
}
/ / Output:
(Tom, 29) (12, 3.14)
Any from template <class T1, class T2>
Ostream & operator<< (ostream & o,const Pair<T1,T2> & p)
The generated function is a friend of any Pair tool board class.
(3) function template as Friend of class
#include <iostream>
Using namespace std;
Class A
{
Int v;
Public:
A(int n):v(n) { }
Template <class T>
Friend void Print(const T & p);
};
Template <class T>
Void Print(const T & p){
Cout << p.v;
}
Int main() {
A a(4);
Print(a);
Return 0;
}
/ / Output: 4
(4) class template as Friend of class template
template <class T>
class B {
T v;
public:
B(T n):v(n) { }
template <class T2>
friend class A;
};
template <class T>
class A {
public:
void Func( ) {
B<int> o(10);
cout << o.v << endl;
}
};
7. Class template and static member variable
A static member can be defined in a class template, all classes that are instantiated from that class template contain the same static members.
#include <iostream>
Using namespace std;
Template <class T>
Class A{
Private:
Static int count;
Public:
A() { count ++; }
~A() { count -- ; };
A( A & ) { count ++ ; }
Static void PrintCount() { cout << count << endl; }
};
Template<> int A<int>::count = 0;
Template<> int A<double>::count = 0;
Int main(){
A<int> ia;
A<double> da;
ia.PrintCount();
da.PrintCount();
Return 0;
}
/ / Output: 1 1