美文网首页
模版特化与偏特化

模版特化与偏特化

作者: eesly_yuan | 来源:发表于2014-09-18 01:12 被阅读1314次

    内容来自

    一是特化为绝对类型; 二是特化为引用,指针类型;三是特化为另外一个类模板。

    • 函数模板的全特化例子如下:
    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);
    }
    
    • 模板有两种特化,全特化和偏特化(局部特化)
      模板函数只能全特化,没有偏特化(以后可能有)。
      模板类是可以全特化和偏特化的。
      全特化,就是模板中模板参数全被指定为确定的类型。
      全特化也就是定义了一个全新的类型,全特化的类中的函数可以与模板类不一样。
      偏特化,就是模板中的模板参数没有被全部确定,需要编译器在编译时进行确定。

    • 在类型上加上const、&、*( cosnt int、int&、int *、等等)并没有产生新的类型。只是类型被修饰了。模板在编译时,可以得到这些修饰信息。

    • 一个特化的模板类的标志:在定义类实现时加上了<>,比如class A<int T>;而在定义一个模板类的时候,class A后面是没有<>的

    • 全特化的标志:template <>然后是完全和模板类型没有一点关系的类实现或者函数定义

    • 偏特化的标志:template <typename T.....>,就是说还剩下点东西,不像全特化<>整得那么彻底


    模板的特化
    • (1)类模板特化
      有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack类模板针对bool类型,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.
    template <class T>
    class stack {};
    template < >
    class stack<bool> { //…// };
    

    上述定义中template < >告诉编译器这是一个特化的模板。

    • (2) 函数模板的特化
      看下面的例子
    main()
    {
      int highest = mymax(5,10);
      char c = mymax(‘a’, ’z’);
      const char* p1 = “hello”;
      const char* p2 = “world”;
      const char* p = mymax(p1,p2);
    }
    

    前面两个mymax都能返回正确的结果.而第三个却不能,因为,此时mymax直接比较两个指针p1 和 p2 而不是其指向的内容.针对这种情况,当mymax函数的参数类型为const char* 时,需要特化。

    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;
    }
    

    现在mymax(p1,p2)能够返回正确的结果了。


    模板的偏特化

    模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化

    • (1) 类模板的偏特化
      例如c++标准库中的类vector的定义
    template <class T, class Allocator>
    class vector { // … // };
    template <class Allocator>
    class vector<bool, Allocator> { //…//};
    

    这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。

    • (2) 函数模板的偏特化
      严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
      template <class T> void f(T);  (a)
      根据重载规则,对(a)进行重载
      template < class T> void f(T\*);  (b)
    

    如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。


    模板特化时的匹配规则
    • (1) 类模板的匹配规则
      最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权
      例子:
    template <class T> class vector{//…//}; // (a)  普通型
    template <class T> class vector<T*>{//…//};  // (b) 对指针类型特化
    template <>   class vector <void*>{//…//};  // (c) 对void*进行特化
    

    每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数

    • (2) 函数模板的匹配规则
      非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权

    相关文章

      网友评论

          本文标题:模版特化与偏特化

          本文链接:https://www.haomeiwen.com/subject/ophutttx.html