代码改变世界

C++类模板的使用

2015-02-02 17:52  sylar_liang  阅读(453)  评论(0编辑  收藏  举报

  模板是一种对类型进行参数化的工具;

  通常有两种形式:函数模板类模板

  函数模板针对仅参数类型不同的函数

  类模板针对仅数据成员成员函数类型不同的类。

1.函数模板

例:

template<class T>
T max(T a, T b)
{
  return (a>b)?a:b;  
}

使用:
int main(int argc, char **argv)
{
  int a = max(1, 2);
  double b = max(2.2, 2.3); 
  return 0;  
}

class可以用typename 关见字代替,在这里typename 和class没区别,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。一但声明了模板函数就可以用模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使用内置类型的地方都可以使用模板形参名。

注意:对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)

 

2.类模板

例:

template<class T1, class T2>

class myclass

{

public:

  T1 a;

  T2 b;

  myclass hy(T1 a, T2 b);

  void show();

};

对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。比如A<2> m;用这种方法把模板形参设置为int是错误的(编译错误:error C2079: 'a' uses undefined class 'A<int>'),类模板形参不存在实参推演的问题。也就是说不能把整型值2推演为int 型传递给模板形参。要把类模板形参调置为int 型必须这样指定A<int> m

类外定义成员函数:

template<class T1, class T2>

myclass<T1, T2>::hy(T1 a, T2 b)

{

  ...

}

template<class T1, class T2>

void myclass<T1, T2>::show()

{

  ...

}

再次提醒注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。

 

3.非类型形参

template<class T, int a> class B{};其中int a就是非类型的模板形参。

非类型模板的形参只能是整型,指针和引用,像double,String, String **这样的类型是不允许的。但是double &,double *,对象的引用或指针是正确的。

调用非类型模板形参的实参必须是一个常量表达式,即他必须能在编译时计算出结果。

当模板的形参是整型时调用该模板时的实参必须是整型的,且在编译期间是常量,比如

template <class T, int a> class A{};如果有int b,这时A<int, b> m;将出错,因为b不是常量,如果const int b,这时A<int, b> m;就是正确的,因为这时b是常量。

非类型模板形参的形参和实参间所允许的转换
1、允许从数组到指针,从函数到指针的转换。如:template <int *a> class A{}; int b[1]; A<b> m;即数组到指针的转换
2、const修饰符的转换。如:template<const int *a> class A{}; int b; A<&b> m;   即从int *到const int *的转换。
3、提升转换。如:template<int a> class A{}; const short b=2; A<b> m; 即从short到int 的提升转换
4、整值转换。如:template<unsigned int a> class A{};   A<3> m; 即从int 到unsigned int的转换。
5、常规转换。

template<typename T, int MAXSIZE>

class Stack{

Private:

       T elems[MAXSIZE];
…

};


Int main()

{

       Stack<int, 20> int20Stack;

       Stack<int, 40> int40Stack;

…

};

 

 

 

 

4.类模板的默认模板类型形参

template<class T1, class T2=int> class A{};为第二个模板类型形参T2提供int型的默认值.

 

在类模板的外部定义类中的成员时template 后的形参表应省略默认的形参类型。比如

template<class  T1, class T2=int>

class A{

public:

  void h();

};

定义方法为

template<class T1,class T2>

void A<T1,T2>::h()

{}