一、何为STL
STL是Standard Template Library的简称,中文名标准模板库,惠普实验室开发的一系列软件的统称。STL是一些容器的合集,其目的在于标准化组件。STL现在是C++的一部分,因此不用安装额外的库文件。
二、模板 template
作用:将类型作为参数,从而编写更加抽象的类和函数。
原本为了实现一致地函数,我们需要不断地将函数重载,可是在模板库的作用下,利用泛型编程只需要提供一个函数即可。
1、函数模板
使用模板前的程序:
#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;
}
使用模板后的程序:
#include <iostream>
#include <typeinfo>
#include <cstring>
using namespace std;
//函数模板 泛型编程
template<typename T>
T mymax(T a,T b){
cout << typeid(T).name() << endl;
return a>b?a:b;
}
//特化版本的函数
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;
}
针对特定的类型,需要些特定的函数版本,否则在编译过程中,会找不到匹配的函数。
求一个数组中的最大值:
#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;
}
2、类模板
以实现堆栈为例:
#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;
}
全特化:虽然函数逻辑相同但是需要将类里的函数全部重写;
#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;
};
//特化版本
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;
}
成员特化:只需将特定的成员函数实现特化的版本;
#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 << "成员特化版本" << endl;
return strcmp(a,b)>0?a:b;
}
*/
T max(){
return a>b?a:b;
}
//声明成员特化的版本
template <const char *>
const char *max();
T min(){
cout << "非物化版本的成员函数" << endl;
return a>b?b:a;
}
//声明成员特化的版本
template <const char*>
const char *min();
/*
{
cout << "成员特化版本" << endl;
return strcmp(a,b)>0?b:a;
}
*/
private:
T a;
T b;
};
//成员函数特化版本的函数
//在类外实现 在类里面实现是没有效果的!!!
template<>
const char * Max<const char*>::max(){
cout << "成员特化版本" << endl;
return strcmp(a,b)>0?a:b;
}
template<>
const char * Max<const char*>::min(){
cout << "成员特化版本" << endl;
return strcmp(a,b)>0?b:a;
}
//不再重写类里的全部函数
/*
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;
}
偏特化:根据特化程序的高低选择实例化合适的类模板;只有类才有,函数的偏特化其实就是重载;
#include <iostream>
using namespace std;
template<typename T,typename K,typename L>
class A{
public:
void show(){
cout << "<T,K,L>" << endl;
}
};
//偏特化
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(){
//根据特化程序的高低选择实例化合适的类模板
A<int,float,double> a;
a.show();
A<int,double,double> b;
b.show();
A<int,int,int> c;
c.show();
//指针的偏特化 TKK T T* T*
A<int,int*,int*> d;
d.show();
//数组的偏特化 T T[] T[]
A<int,int[],int[]> e;
e.show();
return 0;
}