模板完全特化,函数重载的重载,类模板的继承

来源:互联网 发布:襄阳中百淘宝生态城 编辑:程序博客网 时间:2024/06/03 18:27

模板完全特化,函数重载的重载,类模板的继承

    模板用于对类或函数的定制。当模板的泛化处理不适合某个特定的数据类型时,可针对这个数据类型给出相应的模板,包括函数模板和类模板。

1、函数模板完全特化

    函数模板完全特化是在函数模板定义后,再用关键字template<>给出特定类型下的函数模板定义,表明它是一个没有任何泛化类型的完全特化模板。

#include <stdio.h>

template <class T>

void func(T a){

printf("hello\n");

}

//函数模板完全特化

template<>

void func<int>(int a){//int类型进行特化

printf("hello there\n");

}

int main(void){

func(2);    //打印hello there 

func('y');  //打印hello

return 0;

}

2、类模板完全特化

    类模板完全特化是在类模板定义后,再用关键字template<>开头,后跟类名及尖括号<>括起来给出的特定类型下的类模板定义。在特化的类模板中,甚至可以定义新的数据成员和成员函数。

#include <stdio.h>

//类模板A

template <class T>

class A{

private:  

T i;

public:

  A(T t){ i=t; }

  T compute(){ return i*i; }

};

//类模板A的完全特化

template<> class A<int>{

  int i;

  int k;  //添加新数据成员

public:

  A(int t){ i=t; printf("hello\n");}  //添加打印

  int compute(){ return i*i*i; }  //改为立方计算

  void f(){} //添加新成员函数

};

int main(void){

  A<double> dObj(2.5);

  A<int> iObj(5); //打印hello

  printf("%f\n", dObj.compute());  //平方计算.25

  printf("%d\n", iObj.compute());  //立方计算

  return 0;

}

3、函数模板重载

    提供了修改函数模板(类成员函数模板)的途径,允许同名的函数模板,可以具有不同的返回值类型和形参类型。编译器根据实际调用的函数参数进行相应的函数模板的选择调用和具现。

#include <stdio.h>

template <class T>

void func(T a){

printf("使用func(T a)模板\n");

}

//函数模板的重载

template<class T1, class T2>

int func(T1 t1, T2 t2){

printf("使用func(T1 t1, T2 t2)模板\n");

return 1;

}

int main(void){

func(30, 60);  //使用重载的函数模板

func(19);

return 0;

}

4、类模板继承

    可以从一个类模板(基类模板)继承生成一个新类模板。继承类模板中可添加新的成员变量和成员函数,以实现类模板的扩充和修改。

#include <stdio.h>

template<class T>

class A{

public: 

void func(T a){

printf("使用func(T a)成员函数模板\n");

}

};

template<class T1, class T2> 

class B: public A<T1>{

public:

void func(T1 t1, T2 t2){

printf("使用func(T1 t1, T2 t2)成员函数模板\n");

}

};

int main(void){

B<int, double> b;

b.func(30, 60);

A<int> a=static_cast<A<int> >(b);

a.func(10);

return 0;

}

5explicit的作用

    explicit一般用来修饰构造函数。表示这个构造函数必须被显式的调用,不能由编译器进行隐式调用或用于做类型转换。

    参数的构造函数会在需要时被用作类型转换函数,explicit禁止了该构造函数用作类型转换函数。如下所示:

class   A  

  {...  

  public:  

          explicit   A(int   i);  

  ...  

  }   

explicitvirtualinline合称为“函数限定符,它们只适用于构造函数。若一个类拥有只带一个参数的构造函数,则可以使用   

MyClass   object(x)   或   

MyClass   object   =   x  

来初始化对象,这实际是进行了从参数类型到类类型的转换。若在构造函数前加上限定符explicit,将不再允许这种转换,即不允许   

MyClass   object   =   x   这种形式。


6.类模板的部分特化(partial specialization)(from c++ primer)

如果类模板有一个以上的模板形参,我们也许想要特化某些模板形参而非全部。使用类模板的部分特化可以做到这一点:

template <class T1,class T2>

class some_template{

//...

};


//patial specialization:fixes T2 as int and allows T1 to vary

template <class T1>

class some_template<T1,int>{

//...

};


类模板的部分特化本身也是模板。部分特化 的定义看来像模板定义,这种定义以关键字template开头,接着是由尖括号(<>)括住的模板形参表。部分特化的模板形参表是对应的类模板定义形参表的子集。