1. 程式人生 > >C++ 函式模板 例項化和具體化

C++ 函式模板 例項化和具體化

https://blog.csdn.net/qq_30835655/article/details/76850894

 

函式模板是C++新增的一種性質,它允許只定義一次函式的實現,即可使用不同型別的引數來呼叫該函式。這樣做可以減小程式碼的書寫的複雜度,同時也便於修改。但是,在程式碼中包含函式模板本身並不會生成函式定義,它只是一個用於生成函式定義的方案。編譯器使用模板為特定型別生成函式定義時,得到的是模板例項(instantiation)。

1 例項化

例項化有兩種形式,分別為顯式例項化和隱式例項化。模板並非函式定義,例項式函式定義。
1.1 顯式例項化(explicit instantiation)

顯式例項化意味著可以直接命令編譯器建立特定的例項,有兩種顯式宣告的方式。

比如存在這麼一個模板函式

template <typename T>
void Swap(T &a, T &b)

第一種方式是宣告所需的種類,用<>符號來指示型別,並在宣告前加上關鍵詞template,如下:
template void Swap<int>(int &, int &);

第二種方式是直接在程式中使用函式建立,如下:

Swap<int>(a,b);

顯式例項化直接使用了具體的函式定義,而不是讓程式去自動判斷。
1.2 隱式例項化(implicit instantiation)

隱式例項化比較簡單,就是最正常的呼叫,Swap(a,b),直接導致程式生成一個Swap()的例項,該例項使用的型別即引數a和b的型別,編譯器根據引數來定義函式例項。


2 具象化(顯式)
思考這麼一個問題,當前的Swap模板交換輸入的兩個物件,可能式基本型別也可能式自定義類。如果有這麼一個需求,需要交換自定義類裡的某一個屬性而不是整個類,那麼Swap模板就不可用,因為Swap模板交換的是整個類。
顯式具體化將不會使用Swap()模板來生成函式定義,而應使用專門為該特定型別顯式定義的函式型別。有兩種定義形式,如下,其中job為使用者自定義類
template <> void Swap(job &a, job &b)
template <> void Swap<job>(job &a, job &b)
顯式具體化在聲明後,必須要有具體的實現,這是與顯示例項化不同的地方。

3 舉例
下面通過一個程式來觀察例項化和具體化,加深理解。

    /*************************************************************************
        > File Name: array.cpp
        > Author:
        > Mail:
        > Created Time: Sat 05 Aug 2017 01:20:31 AM PDT
     ************************************************************************/
     
    #include<iostream>
    #include<string>
    using namespace std;
     
    struct job
    {
        string name;
        int salary;
        job(string _name,int _salary):name(_name),salary(_salary){};
    };
     
    //template prototype
    template <typename T>
    void Swap(T &a, T &b){
        T temp;
        temp = a;
        a = b;
        b = temp;
    }
     
    //explict specialization for job 顯式具體化
    template <> void Swap(job &a, job &b)
    {
        int temp;
        temp = a.salary;
        a.salary = b.salary;
        b.salary = temp;
    }
     
    template void Swap<int>(int &, int &);
    int main()
    {
        char a = 'a', b = 'b';
        cout<<"a: "<<a<<" ; b: "<<b<<endl;
        Swap(a,b);  //1 implicit template instantiation for char 隱式例項化
        cout<<"a: "<<a<<" ; b: "<<b<<endl;
     
        int c = 1, d = 2;
        cout<<"c: "<<c<<" ; d: "<<d<<endl;
        Swap(c,d);  //2 use explicit template instantiation for int 顯式例項化
        cout<<"c: "<<c<<" ; d: "<<d<<endl;
       
        Swap<int>(c,d);  //3 use explict template instantiation for int 顯式例項化
        cout<<"c: "<<c<<" ; d: "<<d<<endl;
        
        job e("lucy",100), f("bob",200);
        cout<<"lucy: "<<e.name<<" "<<e.salary<<" ; bob: "<<f.name<<" "<<f.salary<<endl;
        Swap(e,f);  //use explict specialization for job 呼叫顯式具體化
        cout<<"lucy: "<<e.name<<" "<<e.salary<<" ; bob: "<<f.name<<" "<<f.salary<<endl;
    }


輸出

    ➜  cpptest ./a.out      
    a: a ; b: b
    a: b ; b: a
    c: 1 ; d: 2
    c: 2 ; d: 1
    c: 1 ; d: 2
    lucy: lucy 100 ; bob: bob 200
    lucy: lucy 200 ; bob: bob 100


備註:隱式例項化和顯式例項化和顯式具體化統稱為具體化,它們的相同在於都用了具體型別的函式定義,而不是通用描述。
---------------------  
作者:尹小賤  
來源:CSDN  
原文:https://blog.csdn.net/qq_30835655/article/details/76850894  
版權宣告:本文為博主原創文章,轉載請附上博文連結!