设为首页 加入收藏

TOP

C++模板的特化(三)
2013-04-24 12:13:11 来源: 作者: 【 】 浏览:736
Tags:模板

 

  特化为另外一个类模板:

  // specialize for vector<T>

  template<class T>

  class Compare<vector<T> >

  {

  public:

  static bool IsEqual(const vector<T>& lh, const vector<T>& rh)

  {

  if(lh.size() != rh.size()) return false;

  else

  {

  for(int i = 0; i < lh.size(); ++i)

  {

  if(lh[i] != rh[i]) return false;

  }

  }

  return true;

  }

  };

  混合型的:

  template<typename T1, typename T2>

  class X {…};

  template<typename T>

  class X<vector<T>, int&> {…}; //至于这里怎么都把T2搞没了变成只依赖一个模板参数T了的问题,大家别着急,我来告诉你个本质的东西,把我这么三点就可以了:1.模板参数个数一致;2.只要template <…>里面有东西不是<>,比如typename T,那么特化时就得用到T;3.不进行任何对模板参数的修饰也是不行的,比如template<typename T> class<T>{…},至少你也得搞个const T之类的吧,呵呵。下面是我搞出来的几种特殊情况,它们都是正确的:

  template<typename T1, typename T2>

  class X {};

  template<typename T>

  class X<vector<T>, T&> {};

  template<typename T>

  class X<vector<T>, int&> {};

  template<>

  class X<vector<double>, int&> {};

  template<typename T1, typename T2, typename T3>

  class X<map<T1,T2>, T3&> {};

  最后,还有一种超级牛X的,在tr1里面用以实现function的,以前我都没见过还可以这么玩的:

  template<typename T>

  class Y;//这是在声明一个类模板,既然声明了,以后就得按这个规矩来,在我们之前的编程(www.cppentry.com)经验里,可以重复声明一个东西没问题,但是为同一个东东重复声明出不同的东西就不可以了,因此你就不能再声明诸如template<typename T1, typename T2> class Y;这样的声明了;其实没有什么是不能声明的,既然我们可以声明变量,声明函数,声明类,那么当然我们也可以声明函数模板或者类模板的。

  template<typename R, typename P1, typename P2>

  class Y<R (P1, P2)> {…};//针对带两个参数,有返回值的函数类型特化,这里R (P1,P2)是定义了一种类型,该类型是一个隐式的函数指针,返回R,参数为P1和P2,这种对函数指针的定义完全等同于R (*)(P1,P2),但是前一种定义很不常见,大家一般是不会注意到这个地方的。

  好了,说了不少关于类模板的特化了,下面再简要说说函数模板的特化:

  函数模板的特化只能是全特化,而不能是偏特化,因此对于函数的特化就比较简单了,就是重新搞一遍就可以了,举几个例子如下:

  template <class T>

  T mymax(const T t1, const T t2)

  {

  return t1 < t2 t2 : t1;

  }

  template <>

  const char* mymax(const char* t1,const char* t2)

  {

  return (strcmp(t1,t2) < 0) t2 : t1;

  }

  但是你不能这么搞:

  template <>

  bool mymax(const char* t1,const char* t2)

  {

  return (strcmp(t1,t2) < 0);

  }

  其实对于mymax这个模板函数的定义而言,是用一个模板参数控制了三个地方,那么你在特化的时候,就也需要用一个特定的类型修改那三处相应的地方,如果你非要返回bool,那么你只能再定义一个函数模板了:

  template <class T>

  bool mymax(const T t1, const T t2)

  {

  return t1 < t2 t2 : t1;

  }

  问题又来了,大家都知道函数重载是不关心返回值的,而只关心参数个数以及类型是否不一致,不一致就是重载,但是对于模板函数而言,这个规矩不再成立,因为任何与模板相关的东西都只是个架子放在那里而已,只要它符合语法规则就可以了,这些架子只是在有人要调用它们时才会发挥效力,也就是说,在编译的时候会为你搜寻合适的模板函数或者类,只要能找到就ok了,而且还要求是只找到一个,要是找到多个也不行,呵呵。

  其实,对于函数而言,虽然不能偏特化,即不能再在函数名字后面像模板类一样搞个<typename T>出来,但是可以通过函数的重载(注意这里说的重载是指的模板重载,而不是普通意义的函数重载)变通的实现偏特化:

  template <typename T1, typename T2>

  bool mymax(T1 t1, T2 t2)

  {

  return t1 < t2 t2 : t1;

  }

  template <typename T1>

  bool mymax(T1 t1, int t2)

  {

  return t1 < t2 t2 : t1;

  }

        

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Floyd(最短路径问题) 下一篇调试秘笈之运行时的错误

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: