C++學習筆記36 模版的顯式具體化和顯式執行個體化,學習筆記36

來源:互聯網
上載者:User

C++學習筆記36 模版的顯式具體化和顯式執行個體化,學習筆記36

C++的模版有時候很可能無法處理某些類型。

例如:

#include <iostream>using namespace std;class man{private:string name;int data;public:man(string s,int i):name(s),data(i){}void show()const{cout<<"this name is "<<name<<" ,data="<<data<<endl;}};template <class T>void mSwap(T t1,T t2){T temp=t1;t1=t2;t2=temp;cout<<"Here are template version "<<t1<<" and "<<t2<<" swap successed!"<<endl;};int main(){mSwap(88,66);man m1("guang",99);man m2("jing",10);mSwap(m1,m2);}
編譯結果:


可以看到會出現很多錯誤。(雖然這不是重點。)

假設我希望mSwap只是交換兩個man的data,而name還保持與原來一樣。該怎麼做呢?

這個時候,就需要我們為特定的類型提供具體化的模版定義了。

具體化包括顯式具體化以及隱式執行個體化和顯式執行個體化。


1.顯式具體化的原型和定義應以template<>開頭,並通過名稱來指出類型。

template<>void mSwap(man &m1,man &m2)
或者

template<>void mSwap<man>(man &m1,man &m2)

修改後的例子:

#include <iostream>using namespace std;class man{private:string name;int data;public:man(string s,int i):name(s),data(i){}void show()const{cout<<"this name is "<<name<<" ,data="<<data<<endl;}void setData(int d){data=d;}int getData()const{return data;}};template <class T>void mSwap(T &t1,T &t2){T temp=t1;t1=t2;t2=temp;cout<<"Here are template version "<<t1<<" and "<<t2<<" swap successed!"<<endl;};template<>void mSwap(man &m1,man &m2){int temp=m1.getData();m1.setData(m2.getData());m2.setData(temp);cout<<"Here are the man version,successed!"<<endl;}int main(){int i=88,j=66;mSwap(i,j);man m1("guang",99);man m2("jing",10);mSwap(m1,m2);m1.show();m2.show();}
運行:


這就是模版顯式具體化的作用了。

需要注意的是,具體化優先於常規模版,而非模版函數優先於具體化和常規模版。


2.執行個體化

要進一步瞭解模版,必須理解術語執行個體化和具體化。記住,在代碼中包含函數模版本身並不會產生函數定義,它只是一個用於產生函數定義的方案。編譯器使用模版為特定類型產生函數定義時,得到的是模版執行個體,例如,上面的mSwap(i,j),函數調用mSwap(i,j)導致編譯器產生mSwap()的一個執行個體,該執行個體使用int類型。

模版並非是函數定義,但使用int的模版執行個體是函數定義。這種執行個體化方式被稱為隱式執行個體化。

C++還可以顯式執行個體化。

文法為,聲明所需的種類--用<>符號指示類型,並在聲明之前加上關鍵字template:

templata void mSwap<man>(man &,man &)

該聲明的意思是“使用mSwap()模版產生man類型的函數定義”。





c++ primer plus中文第5版 講解顯示具體化與執行個體具體化不是很清楚

這一塊是有點痛苦。經過我長時間的總結與分析。得到簡單點的:
先說顯示具體化:
聲明:template<class T>
void test(T t); //這個在顯示具體化中為一般的模板函數
template<> void test<int> (int a); //【顯示具體化函數】

定義: template<class T>
void test(T t){ .....}
template<> void test<int>(int a){ ......}

調用:直接用函數名稱即可
如:test(3); //參數為int,調用具體化
test(3.3); //參數不為int, 調用一般模板函數

再看一下執行個體具體化:
聲明:template<class T>
void test(T t);
void test(float f);

定義:template<class T>
void test(T t){......} //【執行個體具體化函數】
void test(float t){.....} //一般函數,拿來對比

調用:【這點區別很大】
template void test<int>(int t); //要先說明一下類型才能調用執行個體具體化
test(3); //參數為int,調用執行個體具體化
test(3.3); //參數不為int, 調用一般函數

從上面可以看出,其實顯示具體化就是【在函式宣告的時候就已經確定了具體類型要調用的具體函數】,而執行個體具體化是【在函數調用的時候去確定一個類型,使其調用具體化的函數】

從這兩個可以看出,兩個執行個體化就是【為了照顧一些你想特殊處理的類型,讓它不按模板進行】,說白了就是搞特殊嘛,呵呵,編程也得有特殊待遇。
以上就是我總結出來的,希望對你有協助。如果你在學習過程中覺得有不對的地方,請指出。呵呵,一起學習,共同提高。
 
函數模板 既然隱式執行個體化可以讓所有類型的實參適用於一個函數模版,那為何還要有顯示執行個體化?

普通情況下,可以使用函數模板的調用過程推匯出其型別參數對應的資料類型(通稱隱式執行個體化),按照C++創始人Bjarne Stroustrup的說法,其一種原因是與類模板等同對待,更重要的原因就是在某些特殊情況下,根本上無法推匯出模板形參對應的類型,此時只能顯式執行個體化,具體原因的描述和樣本可以參見Bjarne Stroustrup 的著作“The Design and Evolution of C ++”的15.6.2節,中文書名叫:C++語言的設計和演化
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.