zoukankan      html  css  js  c++  java
  • C++ 模板特化

    1.模板特化的定义

    C++中的模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。

    1.1函数模板特化

    函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本。查看如下例:
    #include <iostream>
    using namespace std;
    template<typename T> T Max(T t1,T t2){
        return (t1>t2)?t1:t2;
    }
      
    typedef const char* CCP;
    template<> CCP Max<CCP>(CCP s1,CCP s2){
        return (strcmp(s1,s2)>0)?s1:s2;
    }
    int main(){
    //调用实例:int Max<int>(int,int)
        int i=Max(10,5);
        //调用显示特化:const char* Max<const char*>(const char*,const char*)
        const char* p=Max<const char*>("very","good");
        cout<<"i:"<<i<<endl;
        cout<<"p:"<<p<<endl;
    }
    

    程序正常编译运行结果:  

    i:10
    p:very
    在函数模板显示特化定义(Explicit Specialization Definition)中,显示关键字template和一对尖括号<>,然后是函数模板特化的定义。该定义指出了模板名、被用来特化模板的模板实参,以及函数参数表和函数体。在上面的程序中,如果不给出函数模板Max<T>在T为const char*时的特化版本,那么在比较两个字符串的大小时,比较的是字符串的起始地址的大小,而不是字符串的内容在字典序中先后次序。
    1.1.1使用函数重载替代函数模板特化
    除了定义函数模板特化版本外,还可以直接给出模板函数在特定类型下的重载形式(普通函数)。使用函数重载可以实现函数模板特化的功能,也可以避免函数模板的特定实例的失效。例如,把上面的模板特化可以改成如下重载函数:
    typedef const char* CCP;
    CCP Max(CCP s1,CCP s2){
        return (strcmp(s1,s2)>0)?s1:s2;
    }
    

    程序运行结果和使用函数模板特化相同。但是,使用普通函数重载和使用模板特化还是有不同之处,主要表现在如下两个方面:

    (1)如果使用普通重载函数,那么不管是否发生实际的函数调用,都会在目标文件中生成该函数的二进制代码。而如果使用模板的特化版本,除非发生函数调用,否则不会在目标文件中包含特化模板函数的二进制代码。这符合函数模板的“惰性实例化”准则。
    (2)如果使用普通重载函数,那么在分离编译模式下,应该在各个源文件中包含重载函数的申明,否则在某些原文件中就会使用模板实例化,而不是重载函数。

    1.3类模板特化

    类模板特化类似于函数模板的特化,即类模板参数在某种特定类型下的具体实现。考察如下代码:
    #include <iostream>
    using namespace std;
      
    template<typename T>class A{
        T num;
    public:
        A(){
            num=T(6.6);
        }
        void print(){
            cout<<"A'num:"<<num<<endl;
        }
    };
      
    template<>class A<char*>{
        char* str;
    public:
        A(){
            str="A' special definition ";
        }
        void print(){
            cout<<str<<endl;
        }
    };
      
    int main(){
        A<int> a1; //显示模板实参的隐式实例化
        a1.print();
        A<char*> a2;//使用特化的类模板
        A2.print();
    }
    

      程序输出结果如下:

    A'num:6
    A' special definition
  • 相关阅读:
    Windows消息机制
    inherited 为什么可以调用父类的private函数? [问题点数:100分,结帖人:h2plus0]
    C++Buidler6中需要注意的几个问题
    BGA封装芯片拆装全程纪实
    Delphi组件开发教程指南(四)组件生成过程(TWinControl)
    Delphi技巧集六 (等待执行完一个外部程序再执行另一个程序)
    C++ Builder高级应用开发指南
    干掉“Spirale”病毒
    完全看懂新世代x86指令集結構
    Delphi 组件撰写常问问题delphi 在整合环境中如何找出组件所产生的问题
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/5374973.html
Copyright © 2011-2022 走看看