Article Directory
8. Templates
Function templates are also called generic programming, it is to establish a common function, function type and parameter types do not specify, but with the type of virtual representatives. This generic function is called a function template.
template <typename T1,typename T2>
Keywords can tell c ++ compiler begins generic programming.
#include<iostream>
using namespace std;
template <typename T>
void myswap(T &a, T &b)
{
T c;
c = a;
a = b;
b = c;
}
int main(int argc, char *argv[])
{
char a = 'a',b = 'b';
myswap<char>(a,b); // <>格式对应于template声明
//myswap(a,b) 可以自动类型推导
cout<<a<<" "<<b<<endl;
cin.get();
return 0;
}
/*
b a
*/
If the pointer is directed to the operation, this statement is:
template <typename T,typename T2>
void func(T *p, T2 n);
8.1 Principle template mechanism
gcc -S
The resulting .s
file in assembly code shows the function call. In fact, the compiler help us generate code based on the function of the function call.
The specific process is twice the compilation process:
- According to the code to compile simple template
- According to the call, replace the parameters again compiled
8.2 template function difference between an ordinary function
Function template will be strictly in accordance with the type of match is not automatically type conversion; ordinary function implicitly casts.
#include<iostream>
using namespace std;
template <typename T>
void myswap(T &a, T &b)
{
cout<<"template"<<endl;
}
void myswap(int a, char b)
{
cout<<"normal"<<endl;
}
int main(int argc, char *argv[])
{
int a = 1;
char b = 'a';
myswap(a,b);
myswap(b,a);
myswap(a,a);
cin.get();
return 0;
}
/*
normal
normal
template
*/
Note that:
- Function templates can be overloaded;
- c ++ compiler priority to normal function;
- If the function can produce a better match, select the template;
- By
<>
selecting a template only.
#include<iostream>
using namespace std;
template <typename T>
void myswap(T &a)
{
cout<<"template"<<endl;
}
void myswap(int a)
{
cout<<"normal"<<endl;
}
int main(int argc, char *argv[])
{
int a = 1;
float b = 1.0;
myswap(a);
myswap(b);
cin.get();
return 0;
}
/*
normal
template
template
*/
8.3 class template
When shows a data structure array, tables, graphs, etc. may be separated data types and algorithms.
Template class itself is abstract, use angle brackets when used <>
to provide data types.
#include<iostream>
using namespace std;
template <typename T>
class MyClass{
private:
T a;
public:
MyClass(T a)
{
this->a = a;
}
void printA()
{
cout<<a<<endl;
}
};
void useMyClass(MyClass<int> &c)
{
c.printA();
}
int main(int argc, char *argv[])
{
MyClass<int> c(1);
useMyClass(c);
cin.get();
return 0;
}
There are three class template function implementations:
- Inside the class
- Outer class, in the same cpp
- Outer class, header files, and different in
hpp
the
Here is the second implementation.
template <typename T>
class A{
protected:
T a;
public:
A(T a)
{
this->a = a;
}
void printA();
};
template <typename T>
void A<T>::printA()
{
cout<<a<<endl;
}
Because the principle is the second compilation of the template, so when it comes to the friend functions, to indicate again<T>
#include<iostream>
using namespace std;
template <typename T>
class A {
public:
T a;
public:
A(T a)
{
this->a = a;
}
friend ostream& operator<< <T>(ostream &out, A &c);
};
template <typename T>
ostream & operator<< (ostream &out, A<T> &c)
{
out << c.a << endl;
return out;
}
Remember, friend functions where it can reload the redirection operator `<< >>! ! ! ! !
The third way:
//头文件
#pragma once
template <typename T>
class A {
public:
T a;
public:
A(T a)
{
this->a = a;
}
friend ostream& operator<< <T>(ostream &out, A &c);
};
//hpp
#include <iostream>
#include "myclass.h"
template <typename T>
ostream & operator<< (ostream &out, A<T> &c)
{
out << c.a << endl;
return out;
}
//main
#include<iostream>
using namespace std;
#include "myclass.hpp"
int main(int argc, char *argv[])
{
A<int> c(1);
cin.get();
return 0;
}
8.3.1 derived class template
To know the share memory size when the parent class inheritance, so still use angle brackets <>
to provide data types.
template <typename T>
class A{
protected:
T a;
public:
A(T a)
{
this->a = a;
}
void printA()
{
cout<<a<<endl;
}
};
class B : public A<int>
{
private:
int b;
public:
B(int a, int b) : A<int>(a)
{
this->b = b;
}
void printB()
{
cout<<b<<endl;
}
};
If the class is derived from a template template class, then do this:
template <typename T>
class A{
protected:
T a;
public:
A(T a)
{
this->a = a;
}
void printA()
{
cout<<a<<endl;
}
};
template <typename T>
class B : public A<T>
{
private:
T b;
public:
B(T a, T b) : A<T>(a)
{
this->b = b;
}
void printB()
{
cout<<b<<endl;
}
};
8.3.2 class template static keyword
Each <T>
, has its own a static variable.