解读C++编程中类模板的三种特化

2020-01-06 14:16:30王冬梅

2.模板局部特化
模板局部特化首先要声明的是,C++还不支持对函数模板的局部特化,所以此处我们只讨论类模板的局部特化.我们依然首先需要一个主模板.(参考类模板显式特化) 自我理解:如果针对不能的指针定义不同的完全特化,岂不是太麻烦了,有没有更好的办法呢?那就是局部特化了.(例1)提示: 局部特化它是一个模板.完全特化不是一样模板.

例1


/***********************************************
 *  局部特化 
 *     和完全特化不同,这里的Heap参数类型只是被部分的确
 *  定为T*,而T是一个未指定的类型,这就是为什么说它是局部
 *  特化的原因;
 *     当使用一个未经任何修饰的指针类型来实例化Heap时,
 *  局部特化将优先于主模板;
 *     当使用const char * 或 char *(参考类模板显式特化)来
 *  实例化Heap时,此时完全特化又会优先于局部特化.
 *  Heap<std::string> h1;  主模板  T是std::string
 *  Heap<std::string *> h2;  局部特化  T是std:string
 *  Heap<int **> h3;    局部特化 T是int *
 *  Heap<char *> h4;  完全特化 T是char *
 *  Heap<const int *> h5;  局部特化 T是const int
 *  Heap<int (*)()> h6;  局部特化 T是int()
***********************************************/
template <typename T>
class Heap<T *> //注意这里
{
private:
  std::vector<T *>h_;
public:
  void push(const T *val);
  T *pop();
  bool empty()
  {
    return h_.empty();
  }
};

template <typename T>
void Heap<T *>::push(const T *val)
{
  //......
}

例2


/***********************************************
 *     有一点很微妙但很有用:主模板的完全特化或局部特化
 *  必须采用与主模板相同数量和类型的实参进行实例化,但它
 *  的模板的参数并不需要具有和主模板相同的形式.
***********************************************/
//定义一个模板,有三个模板参数,书写形式如下
template <typename R,typename A1,typename A2> 
//注意,局部特化中,模板参数也是三个,但书写形式可不一样喽
class Heap<R (*) (A1,A2)>
{
  //......
};

Heap<char *(*) (int,int)> h7; //R是char *,A1和A2是int
//把 char *(*) (int,int) 想象成一个"指向有两个参数的非成员函数的指针"

template <class C,typename T>
class Heap<T C::*>
{
  //......
};
Heap<std::string Name::*> h8;//T是string,C是Name

尽管为何需要对这些东西使用Heap只是一个猜测,先知道有这么一用法吧!

3.类模板成员特化

虽然模板的特化和类的派生之间没有任何关系, 但在特化模板的时候,不妨借鉴一下派生的精神.也就意味着一个完全特化或局部特化通常必须重新实现 主模板具备的所有能力.