Introduction
Template refers to the programming of C + + programming language which adopts type as parameter, and supports the general program design. The standard library of C + + provides many useful functions that mostly combine the concepts of templates, such as STL and IO Stream.
function Templates
In the introduction of C + +, a lot of people will touch swap (int&, int&) Such functions like code as follows:
void swap (Int&a, int& b) {
int temp = A;
A = b;
b = temp;
}
However, if you want to support long,string, custom class swap function, the code is similar to the above code, but the type is different, this is our definition of swap function template, we can reuse the different types of swap function code, function template declaration form as follows:
Template <class identifier> function_declaration;
Template <typename identifier> function_declaration;
The Declaration and definition code for the Swap function template is as follows:
Method.h
Template<typename t> void Swap (t& t1, t& T2);
#include "Method.cpp"
Method.cpp
Template<typename t> void swap (t& t1, t& T2) {
T tmpt;
tmpt = T1;
T1 = T2;
t2 = tmpt;
}
The above is the Declaration and definition of the template, that template how to instantiate it, the template instantiation is what the compiler does, not the programmer, then how to use the above template, the code is as follows:
Main.cpp
#include <stdio.h>
#include "Method.h"
int main () {
int NUM1 = 1, num2 = 2;
Swap<int> (NUM1, num2);
printf ("num1:%d, num2:%d\n", NUM1, num2);
return 0;
}
Using the swap function here, you must include the definition of Swap, otherwise the compilation will go wrong, which is not the same as the normal function. You must add # include "Method.cpp" to the last line of the Method.h file.
class Template
Consider we write a simple stack of classes, this stack can support int type, long type, string type, etc., do not use class template, we will write more than three stack class, where the code is basically the same, through the class template, we can define a simple stack template, then instantiate the int stack as needed, long stack, string stack.
Statck.h
Template <class t> class Stack {
Public
Stack ();
~stack ();
void push (T t);
T pop ();
BOOL IsEmpty ();
Private
T *m_pt;
int m_maxsize;
int m_size;
};
#include "Stack.cpp"
Stack.cpp
Template <class t> stack<t>::stack () {
m_maxsize = 100;
m_size = 0;
M_pt = new T[m_maxsize];
}
Template <class t> stack<t>::~stack () {
delete [] m_pt;
}
Template <class t> void stack<t>::p ush (T t) {
m_size++;
M_pt[m_size-1] = t;
}
Template <class t> T stack<t>::p op () {
T t = m_pt[m_size-1];
m_size--;
return t;
}
Template <class t> bool Stack<t>::isempty () {
return m_size = = 0;
}
The above defines a class template-the stack, which is very simple, just to illustrate how the class template is used, up to 100 elements can be supported in the stack, using the following example:
Main.cpp
#include <stdio.h>
#include "Stack.h"
int main () {
Stack<int> IntStack;
Intstack.push (1);
Intstack.push (2);
Intstack.push (3);
while (!intstack.isempty ()) {
printf ("num:%d\n", Intstack.pop ());
}
return 0;
}
Template parameters
A template can have a type parameter, or it can have a regular type parameter int, or it can have default template parameters, such as
Template<class T, T def_val> class stack{...}
There is a limit to the stack of the above class template, that is, we can only support up to 100 elements, we could use the template parameters to configure the maximum number of elements of this stack, if not configured, set the default maximum value is 100, the code is as follows:
Statck.h
Template <class T,int maxsize = 100> class Stack {
Public
Stack ();
~stack ();
void push (T t);
T pop ();
BOOL IsEmpty ();
Private
T *m_pt;
int m_maxsize;
int m_size;
};
#include "Stack.cpp"
Stack.cpp
Template <class t,int maxsize> stack<t, Maxsize>::stack () {
M_maxsize = maxSize;
m_size = 0;
M_pt = new T[m_maxsize];
}
Template <class t,int maxsize> stack<t, Maxsize>::~stack () {
delete [] m_pt;
}
Template <class t,int maxsize> void Stack<t, Maxsize>::p ush (T t) {
m_size++;
M_pt[m_size-1] = t;
}
Template <class t,int maxsize> T stack<t, Maxsize>::p op () {
T t = m_pt[m_size-1];
m_size--;
return t;
}
Template <class t,int maxsize> bool stack<t, Maxsize>::isempty () {
return m_size = = 0;
}
Examples of use are:
Main.cpp
#include <stdio.h>
#include "Stack.h"
int main () {
int maxsize = 1024;
Stack<int,1024> IntStack;
for (int i = 0; i < maxsize; i++) {
Intstack.push (i);
}
while (!intstack.isempty ()) {
printf ("num:%d\n", Intstack.pop ());
}
return 0;
}
Template Specialization
When we want to define different implementations of the template, we can use the specialization of the template. For example, we define the Stack class template, if it is a stack of type char*, we want to be able to copy all the data of char into the stack class, because only the char pointer is saved, the memory that the char pointer points to is likely to be invalidated, the stack element char pointer pops up, The memory pointed to may already be invalid. And our definition of the Swap function template, in the case of vectors or lists and other container types, if the container holds large objects, it will consume a lot of memory, performance degradation, because to produce a temporary large object save a, which requires template specialization to solve.
function template Specialization
Assuming that we have a swap function to handle a situation, we have two vector<int> of many elements, and when using the original swap function, execute tmpt = T1 to copy all the elements of T1, consume a lot of memory, cause performance degradation, So our system solves this problem through the Vector.swap function, the code is as follows:
Method.h
Template<class t> void Swap (t& t1, t& T2);
#include "Method.cpp"
#include <vector>
using namespace Std;
Template<class t> void Swap (t& t1, t& T2) {
T tmpt;
tmpt = T1;
T1 = T2;
t2 = tmpt;
}
template<> void Swap (std::vector<int>& t1, std::vector<int>& T2) {
T1.swap (T2);
}
The template<> prefix indicates that this is a specialization, described without template parameters, using the example below:
Main.cpp
#include <stdio.h>
#include <vector>
#include <string>
#include "Method.h"
int main () {
using namespace Std;
String str1 = "1", str2 = "2";
Swap (str1, str2);
printf ("str1:%s, str2:%s\n", Str1.c_str (), Str2.c_str ());
Vector<int> v1, v2;
V1.push_back (1);
V2.push_back (2);
Swap (v1, v2);
for (int i = 0; i < v1.size (); i++) {
printf ("v1[%d]:%d\n", I, v1[i]);
}
for (int i = 0; i < v2.size (); i++) {
printf ("v2[%d]:%d\n", I, v2[i]);
}
return 0;
}
Vector<int> swap code is still relatively limited, if you want to use template specialization to solve all the vector swap, how to do it, only need to put the following code
template<> void Swap (std::vector<int>& t1, std::vector<int>& T2) {
T1.swap (T2);
}
Switch
Template<class v> void Swap (std::vector<v>& t1, std::vector<v>& T2) {
T1.swap (T2);
}
Yes, the rest of the code does not change.
Class template Specialization
Take a look at the following compare code:
Compare.h
Template <class t>
Class Compare
{
Public
bool Equal (t T1, T T2)
{
return T1 = = T2;
}
};
#include <iostream>
#include "compare.h"
int main ()
{
using namespace Std;
Char str1[] = "Hello";
Char str2[] = "Hello";
Compare<int> C1;
Compare<char *> C2;
cout << c1.equal (1, 1) << Endl; Compare parameters of two int types
cout << c2.equal (str1, str2) << Endl; Compare parameters of two char * types
return 0;
}
When comparing two integers, the equal method of compare is correct, but the template parameter of compare is char*, the template will not work, so modify the following:
Compare.h
#include <string.h>
Template <class t>
Class Compare
{
Public
bool Equal (t T1, T T2)
{
return T1 = = T2;
}
};
Template<>class Compare<char *>
{
Public
bool Equal (char* T1, char* T2)
{
Return strcmp (t1, t2) = = 0;
}
};
The main.cpp file does not change, and this code works correctly.
Template Type Conversions
Remember our custom stack template, in our program, suppose we defined the shape and circle class with the following code:
Shape.h
Class Shape {
};
Class Circle:public Shape {
};
Then we want to use it like this:
Main.cpp
#include <stdio.h>
#include "Stack.h"
#include "shape.h"
int main () {
Stack<circle*> Pcirclestack;
Stack<shape*> Pshapestack;
Pcirclestack.push (new Circle);
Pshapestack = Pcirclestack;
return 0;
}
This is not compiled, because stack<shape*> is not the parent of stack<circle*>, but we want the code to work, then we need to define the conversion operator, the stack code is as follows:
Statck.h
Template <class t> class Stack {
Public
Stack ();
~stack ();
void push (T t);
T pop ();
BOOL IsEmpty ();
Template<class t2> operator stack<t2> ();
Private
T *m_pt;
int m_maxsize;
int m_size;
};
#include "Stack.cpp"
Template <class t> stack<t>::stack () {
m_maxsize = 100;
m_size = 0;
M_pt = new T[m_maxsize];
}
Template <class t> stack<t>::~stack () {
delete [] m_pt;
}
Template <class t> void stack<t>::p ush (T t) {
m_size++;
M_pt[m_size-1] = t;
}
Template <class t> T stack<t>::p op () {
T t = m_pt[m_size-1];
m_size--;
return t;
}
Template <class t> bool Stack<t>::isempty () {
return m_size = = 0;
}
Template <class t> template <class t2> stack<t>::operator stack<t2> () {
Stack<t2> StackT2;
for (int i = 0; i < m_size; i++) {
Stackt2.push ((T2) m_pt[m_size-1]);
}
return StackT2;
}
Main.cpp
#include <stdio.h>
#include "Stack.h"
#include "shape.h"
int main () {
Stack<circle*> Pcirclestack;
Stack<shape*> Pshapestack;
Pcirclestack.push (new Circle);
Pshapestack = Pcirclestack;
return 0;
}
This allows the,stack<circle> or stack<circle*> to be automatically converted to stack<shape> or STACK<SHAPE*>, if the type of conversion is stack< Int> to Stack<shape> the compiler will error.
Other
A class does not have a template parameter, but the member function has a template parameter, which is feasible and the code is as follows:
Class Util {
Public
Template <class t> bool equal (t T1, T T2) {
return T1 = = T2;
}
};
int main () {
Util Util;
int a = 1, b = 2;
Util.equal<int> (1, 2);
return 0;
}
You can even declare util's equal as static, with the following code:
classUtil { Public: Template<classT>Static BOOLequal (t T1, T T2) {returnT1 = =T2; }};intMain () {intA =1, B =2; Util::equal<int> (1,2); return 0;}
See: http://www.cnblogs.com/ggjucheng/archive/2011/12/18/2292090.html
Go C + + Template