I. What is STL
STL is the abbreviation of Standard Template Library, the Chinese name standard template library, and the general name of a series of software developed by HP Labs. STL is a collection of containers designed to standardize components. STL is now part of C++, so no additional library files need to be installed.
Template template
Function: Write more abstract classes and functions by taking types as parameters.
Originally, in order to achieve a consistent function, we need to constantly overload the function, but under the function of template library, generic programming only needs to provide a function.
1. Function Template
Procedures before using templates:
#include <iostream> #include <cstring> using namespace std; char mymax(char a,char b){ cout << "char " << endl; return a>b?a:b; } int mymax(int a,int b){ cout << "int " << endl; return a>b?a:b; } double mymax(double a,double b){ cout << "double " << endl; return a>b?a:b; } const char *mymax(const char* a,const char* b){ //return a>b?a:b; return strcmp(a,b)>0?a:b; } int main(){ mymax('a','b'); mymax(1,3); mymax(1.2,3.4); short a=1,b=2; mymax(a,b); mymax("hello","world"); //mymax(1,2.34);//mymax(int,double) --> mymax(int,int) mymax(double,double) return 0; }
After using the template, the program:
#include <iostream> #include <typeinfo> #include <cstring> using namespace std; //Function Template Generic Programming template<typename T> T mymax(T a,T b){ cout << typeid(T).name() << endl; return a>b?a:b; } //Special version of functions template<> const char* mymax<const char*>(const char* a,const char* b){ cout << "const char*" << endl; return strcmp(a,b)>0?a:b; } int main(){ cout << mymax<int>(1,3) << endl; cout << mymax<double>(3.14,2.39) << endl; cout << mymax<char>('a','b') << endl; cout << mymax<double>('a','b') << endl; cout << mymax<const char*>("hello","world") << endl; return 0; }
Specific function versions are required for specific types, otherwise matching functions will not be found during compilation.
Find the maximum in an array:
#include <iostream> #include <cstring> using namespace std; template<typename K> K maxOfArr(K arr[],size_t len){ K m = arr[0]; for(size_t i=0;i<len;i++){ if(m < arr[i]){ m = arr[i]; } } return m; } //Special version of functions template<> const char* maxOfArr<const char*>(const char* arr[],size_t len){ const char *m = arr[0]; for(int i=0;i<len;i++){ if(strcmp(m,arr[i])<0){ m = arr[i]; } } return m; } int main(){ int arr[3] = {1,3,2}; cout << maxOfArr<int>(arr,3) << endl; double brr[4] = {1,2.3,3.2,2.7}; cout << maxOfArr<double>(brr,4) << endl; const char * crr[5] = {"zhaoyun","guanyu","machao","huangzhong","zhangfei"}; cout << maxOfArr<const char*>(crr,5) << endl; cout << maxOfArr(arr,3) << endl; cout << maxOfArr(brr,4) << endl; cout << maxOfArr(crr,5) << endl; return 0; }
2. Class Template
Take the implementation of the stack as an example:
#include <iostream> #include <cstring> using namespace std; template<typename K> K maxOfArr(K arr[],size_t len){ K m = arr[0]; for(size_t i=0;i<len;i++){ if(m < arr[i]){ m = arr[i]; } } return m; } template<> const char* maxOfArr<const char*>(const char* arr[],size_t len){ const char *m = arr[0]; for(int i=0;i<len;i++){ if(strcmp(m,arr[i])<0){ m = arr[i]; } } return m; } int main(){ int arr[3] = {1,3,2}; cout << maxOfArr<int>(arr,3) << endl; double brr[4] = {1,2.3,3.2,2.7}; cout << maxOfArr<double>(brr,4) << endl; const char * crr[5] = {"zhaoyun","guanyu","machao","huangzhong","zhangfei"}; cout << maxOfArr<const char*>(crr,5) << endl; cout << maxOfArr(arr,3) << endl; cout << maxOfArr(brr,4) << endl; cout << maxOfArr(crr,5) << endl; return 0; }
Full specialization: Although the function logic is the same, it needs to rewrite all the functions in the class.
#include <iostream> #include <cstring> using namespace std; template<typename T> class Max{ public: void show(){ cout << a << " : " << b << endl; } Max(T a,T b):a(a),b(b){ cout << "T" << endl; } T max(){ return a>b?a:b; } T min(){ return a>b?b:a; } private: T a; T b; }; //special version template<> class Max<const char *>{ public: Max(const char* a,const char *b):a(a),b(b){ cout << "const char*" << endl; } void show(){ cout << a << " : " << b << endl; } const char *max(){ return strcmp(a,b)>0?a:b; } const char *min(){ return strcmp(a,b)>0?b:a; } private: const char* a; const char* b; }; int main(){ Max<int> m1(1,3); cout << m1.max() << endl; Max<double> m2(2.3,2.1); cout << m2.min() << endl; Max<const char*> m3("Hello","World"); cout << m3.max() << endl; m3.show(); return 0; }
Membership specialization: only a special version of the member function is needed;
#include <iostream> #include <cstring> using namespace std; template<typename T> class Max{ public: void show(){ cout << a << " : " << b << endl; } Max(T a,T b):a(a),b(b){ cout << "T" << endl; } /* template <const char*> const char *max(){ cout << "Membership specialization version "<< endl; return strcmp(a,b)>0?a:b; } */ T max(){ return a>b?a:b; } //Specialized versions of declaration Members template <const char *> const char *max(); T min(){ cout << "Membership functions in non-materialized versions" << endl; return a>b?b:a; } //Specialized versions of declaration Members template <const char*> const char *min(); /* { cout << "Membership specialization version "<< endl; return strcmp(a,b)>0?b:a; } */ private: T a; T b; }; //Functions in the Specialized Version of Membership Functions //It is not effective to implement outside class and inside class!!! template<> const char * Max<const char*>::max(){ cout << "Membership specialization version" << endl; return strcmp(a,b)>0?a:b; } template<> const char * Max<const char*>::min(){ cout << "Membership specialization version" << endl; return strcmp(a,b)>0?b:a; } //No longer rewrite all functions in a class /* template<> class Max<const char *>{ public: Max(const char* a,const char *b):a(a),b(b){ cout << "const char*" << endl; } void show(){ cout << a << " : " << b << endl; } const char *max(){ return strcmp(a,b)>0?a:b; } const char *min(){ return strcmp(a,b)>0?b:a; } private: const char* a; const char* b; }; */ int main(){ Max<int> m1(1,3); cout << m1.max() << endl; Max<double> m2(2.3,2.1); cout << m2.min() << endl; Max<const char*> m3("Hello","World"); cout << m3.max() << endl; cout << m3.min() << endl; m3.show(); return 0; }
Partialization: Select the appropriate class template according to the level of the specialization program; only the class has, function partialization is actually overloading;
#include <iostream> using namespace std; template<typename T,typename K,typename L> class A{ public: void show(){ cout << "<T,K,L>" << endl; } }; //partial specialization template<typename T,typename K> class A<T,K,K>{ public: void show(){ cout << "<T,K,K>" << endl; } }; template<typename T> class A<T,T,T>{ public: void show(){ cout << "<T,T,T>" << endl; } }; template<typename T> class A<T,T*,T*>{ public: void show(){ cout << "<T,T*,T*>" << endl; } }; template<typename T> class A<T,T[],T[]>{ public: void show(){ cout << "<T,T[],T[]>" << endl; } }; int main(){ //Select the appropriate class template to instantiate according to the level of the Specialization program A<int,float,double> a; a.show(); A<int,double,double> b; b.show(); A<int,int,int> c; c.show(); //Pointer Partialization TKK T*T* A<int,int*,int*> d; d.show(); //Partialization of arrays T [] T [] A<int,int[],int[]> e; e.show(); return 0; }