首页 > 代码库 > C++ 模板

C++ 模板

0.前言

模板是一种通用的描述机制,当使用模板时,允许使用通用类型来定义函数或类。通用类型可被具体类型(如int,double甚至是用户自定义类型)来代替。模板引入了一个全新的编程思维方式,称为“泛型编程”或者“通用编程”。

1.函数模板

1)函数模板声明形式如下:

template  <class(或typename) A,...,int B (常数)>返回类型   函数名(参数列表){    //函数体}

class用于定义类,在模板引入c++后,最初定义模板的方法为:template<class T>,这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同class一样表明后面的符号为一个类型。

2)函数模板的使用

函数模板定义形式如下:

template  <class T1[,  class T2, ......]>函数原型;

3)函数模板实例化

3.1)隐式实例化:

技术分享
 1 /*************************main.c********************/ 2 #include <iostream.h> 3 using namespace std; 4 template<class Ex> 5 Ex  Greater(Ex x,Ex y); 6  7 int main() 8 { 9     int inx=1;iny=2;10     cout<<Greater(inx,iny)<<endl;   //实参为int类型,生产int型模板函数,并对第二个进行实参检查11     return 0;12 }13 14 template<class Ex>15 Ex  Grearer(Ex x,Ex y)16 {17     return x>y?x:y;18 }
View Code

输出结果如下为2;

3.2)显示实例化标准格式如下:

template  返回类型   函数名<类型实参表>  (函数参数表)
技术分享
 1 /*************************main.c********************/ 2 #include <iostream.h> 3 using namespace std; 4 template<class Ex> 5 Ex  Greater(Ex x,Ex y); 6  7 template  int  Greater<int>  (int,int); 8  9 int main()10 {11     int inx=1;iny=2;12     cout<<Greater(inx,iny)<<endl;   //调用实例化模板函数13     return 0;14 }15 16 template<class Ex>17 Ex  Grearer(Ex x,Ex y)18 {19     return x>y?x:y;20 }
View Code

3.3)利用特化可以解决某些类型在函数中的特殊操作,特化的基本格式如下:

template<>  返回类型  函数名[(类型实参表)](函数参数表)

其中类型实参表可以省略,有后续的函数参数表来指定。

技术分享
 1 /*************************main.c********************/ 2 #include <iostream.h> 3 using namespace std; 4 template<class Ex> 5 Ex  Greater(Ex x,Ex y); 6  7 template<>  double  Greater<double>(double,double);   //特化声明 8  9 int main()10 {11     int inx=1;iny=2;12     double dbx = 3.0,dby = 2.9;13     cout<<Greater(inx,iny)<<endl;      //隐式实例化14     cout<<Greater(dbx,dby)<<endl;    //优先调用特化函数15     return 0;16 }17 18 template<class Ex>19 Ex  Grearer(Ex x,Ex y)20 {21     return x>y?x:y;22 }23 24 template<>  double  Greater(double x,double y)   //特化定义25 {26     return x+y;27 }
View Code

输出结果为:

技术分享
1 22 5.9
View Code

3.4)优先级和执行顺序

一般函数的执行顺序优先于模板的特化函数,模板的特化函数优先于实例化函数。

更特化的含义体现在“编译器做决定是执行的转换最少”,c++遵循部分排序规则来选择最优化模板函数。

技术分享
 1 template<class T>  void  f(T) {}        #1 2 template<class T>  void  f(T*) {}        #2 3 template<class T>  void  f(const T*) {}        #3 4 template<class T>  void  g(T) {}        #4 5 template<class T>  void  g(T&) {}        #5 6  7 int main() 8 { 9     const int *p;10     f(p);11     int q;12     //g(q);13 }
View Code

模板#2比模板1更特化,模板3比模板2更特化,因此f(p)调用#3。然而模板#4和#5没有谁比谁更特化,因此g(q)会带来二义性错误。

2.类模板

1)类模板的定义

template<class 模板参数表>class 类名{    // 类定义};

2)类模板实例化

2.1)隐式实例化

首先定义类模板:

技术分享
 1 template  <class T,int num> 2 class Stack 3 { 4     private: 5         T  sz[num]; 6         int point; 7     public: 8         Stack(); 9         ...10 }11 12 template<class T,int num>13 Stack<T,num>::Stack()14 {15     point = 0;16 }
View Code

然后使用一下语句隐式实例化:

Stack<int,10> st;

下述语句不需要创建对象,编译器不会隐式生成类定义:

Stack<int,10> *ps;

2.2)显示实例化

template  class 类名<类型参数表>

2.3)显示特化

template<>  class 类名<特殊类型>{     类定义;}

2.4)部分特化

template<class T1 , class T2> class Example{   //类定义};部分特化定义为:template<class T2> class Example<int ,T2>{   //类定义}

3)模板的嵌套

3.1)函数成员模板

成员模板不能声明为虚函数。

技术分享
 1 #include <iostream.h> 2 using namespace std; 3 template<class A> 4 class Test 5 { 6     public: 7         template<class B> 8          A f(B); 9 };10 11 template<class A>12 template<class B>13 A Test<A>::f(B)14 {15    return A(B);16 }17 18 int main()19 {20     Test<int> t;21     cout<<t.f(3.14)<<endl;22     return 0;23 }
View Code

输出结果是:3

3.2)对象成员模板

类模板的定义可以放在另一个类中,实例化后的模板对象可以作为另一个类的成员。

技术分享
 1 #include <iostream.h> 2 using namespace std; 3 template<class T> 4 class Outside 5 { 6     public: 7         template<class R> 8         class Inside 9         {10              private:11                   R r;12              public:13                   Inside(R r)     //类模板的成员函数可以在定义时实现14                   {15                       r = x;16                    }17              void disp();18         };19        void disp();20      private:21           Inside<T> t;22 } ;23 24 template<class T>25 template<class R>26 void Outside<T>::Inside<R>::disp()    //类模板的成员函数也可以在定义外实现27 {28     cout<<"Inside: "<<Outside<T>::Inside<R>::r<<endl;29 }30 31 template<class T>32 void  Outside<T>::disp()33 {34     cout<<"Outside:";35    t.disp();36 }37 38 int main()39 {40     Outside<int>::Inside<double> obin(3.5);  //声明Inside类对象41     obin.disp();42     Outside<int> obout(2);                          //创建Outside对象obout43     obout.disp();44     return 0;45 }
View Code

输出结果如下:

技术分享
Inside:  3.5Outside:Inside:  2
View Code

4)模板参数

模板可以作为另一个模板的参数类型,形式如下:

template<template <class T1> class T2,class T3,int Num>;
技术分享
 1 #include <iostream> 2 using namespace std; 3  4 template<class T,int num> 5 class Stack 6 { 7     private: 8          T sz[num]; 9     public:10          int ReturnNum();  11 };12 template<class T1,int num1>13 int Stack(T1,num1>::ReturnNum()14 {15      return num1;16 }17 18 template<template<class Type,int NUM> class TypeClass,class T1,int N>19 void  disp()20 {21      TypeClass<T1,N> ob;     //类模板的隐式实例化,创建对象ob22      cout<<ob.ReturnNum()<<endl;23 }24 25 int main()26 {27    disp<Stack,int,8>();28    return 0;29 }
View Code

输出结果为:8。

 

C++ 模板