生活随笔
收集整理的這篇文章主要介紹了
c++模板显示实例化,显示具体化,隐式实例化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
函數模板是C++新增的一種性質,它允許只定義一次函數的實現,即可使用不同類型的參數來調用該函數。這樣做可以減小代碼的書寫的復雜度,同時也便于修改(注:使用模板函數并不會減少最終可執行程序的大小,因為在調用模板函數時,編譯器都根據調用時的參數類型進行了相應實例化)。下面來看看函數模板的使用過程:
[cpp]?view plaincopy
struct?job?? {?? ????char?name[20];?? ????int?salary;?? };?? ?? template?<class?T>??? void?swap(T?&a,?T?&b);?? ?? void?showJob(const?job?&a);?? ?? using?std::cin;?? using?std::cout;?? using?std::endl;?? void?main(void)?? {?? ?? ????int?a?=?4;?? ????int?b?=?5;?? ????cout<<"Before?swap?a?=?"<<a<<"?b="<<b<<endl;?? ????swap(a,?b);?? ????cout<<"After?swap?a?=?"<<a<<"?b="<<b<<endl;?? ????? ????job?jobA?=?{"coder",?10000};?? ????job?jobB?=?{"manager",?1000};???? ????cout<<"Before?swap";?? ????showJob(jobA);?? ????showJob(jobB);?? ????cout<<endl;?? ????swap(jobA,?jobB);?? ????cout<<"After?swap";?? ????showJob(jobA);?? ????showJob(jobB);?? ????cout<<endl;?? system("pause");?? };?? ?? template<class?T>??? void?swap(T?&a,?T?&b)?? {?? ????T?temp;?? ????temp?=?a;?? ????a?=?b;?? ????b?=?temp;?? }?? ?? void?showJob(const?job?&a)?? {?? cout<<"?"<<a.name<<"?=?"<<a.salary;?? }??
如果在上述job結構互換過程中只想互換salary,而不換其他成員變量值那么怎么辦呢?C++中可以通過以下幾種方法來解決這一問題。
1>顯式具體化
顯式具體化也是基于函數模板的,只不過在函數模板的基礎上,添加一個專門針對特定類型的、實現方式不同的具體化函數。
[cpp]?view plaincopy
template<>void?swap<job>(job?&a,?job?&b)?? {?? ?????int?salary;?? ?????salary?=?a.salary;?? ?????a.salary?=?b.salary;?? ?????b.salary?=?salary;?? }??
如上所示,該具體化函數的實現與模板并不一致,編譯器解析函數調用時會選擇最匹配的函數定義。
2>定義同名常規函數
[cpp]?view plaincopy
void?swap(job?&a,?job?&b)?? {?? ?????int?salary;?? ?????salary?=?a.salary;?? ?????a.salary?=?b.salary;?? ?????b.salary?=?salary;?? }??
由于編譯器在重載解析時,會選擇最匹配函數定義,所以在調用swap(jobA, jobB)時,編譯器會選擇void swap(job &a, job &b)函數定義,而屏蔽了模板函數。
同時,模板函數也可以重載,其操作與常規函數一致。
[cpp]?view plaincopy
template?<class?T>?void?swap(T?&a,?T?&b);?? ?? template?<class?T>?void?swap(T?&a,?T?&b,?T?&c);?? ?? ?? template?<typename?T>?void?swap(T?&a,?T?&b)?? {?? ????T?temp;?? ????temp?=?a;?? ????a?=?b;?? ????b?=?temp;?? }?? ?? template?<typename?T>?void?swap(T?&a,?T?&b,?T?&c)?? {?? ????T?temp;?? ????temp?=?a;?? ????a?=?b;?? ????b?=?c;?? ????c?=?temp;?? }??
上面主要說的是函數模板的具體化,下面說下模板實例化。
函數模板:
[cpp]?view plaincopy
#define?MAXNAME?128?? struct?job?? {?? char?name[MAXNAME]:?? int?salary;?? };?? ?? template<class?T>?? void?swap(T?&a,?T?&b?)?? {?? ??T?temp;?? ??temp?=?a;?? ??a?=?b;?? ??b?=?temp;?? };?? ?? template?void?swap<int>(int?&a,?int?&?b);???? ?? template<>?void?swap<job>(job?&a,?job?&b)????? {?? ??int?salary:?? ??salary?=?a.salary:?? ??a.salary?=?b.salary;?? ??b.salary?=?salary;?? };??
類模板:
[cpp]?view plaincopy
template?<class?T>?? class?Arrary?? {?? private:?? ??T*?ar;?? ??int?l;?? ...?? };?? ?? template?class?Array<int>;????? ?? template<>?class?Array<job>?? {?? private:?? ??job*?ar;?? ??int?l;?? };??
相應的,隱式實例化指的是:在使用模板之前,編譯器不生成模板的聲明和定義實例。只有當使用模板時,編譯器才根據模板定義生成相應類型的實例。如:
int i=0, j=1;
swap(i, j); ?//編譯器根據參數i,j的類型隱式地生成swap<int>(int &a, int &b)的函數定義。
Array<int> arVal;//編譯器根據類型參數隱式地生成Array<int>類聲明和類函數定義。
顯式實例化:
當顯式實例化模板時,在使用模板之前,編譯器根據顯式實例化指定的類型生成模板實例。如前面顯示實例化(explicit instantiation)模板函數和模板類。其格式為:
template typename function<typename>(argulist);
template class classname<typename>;
顯式實例化只需聲明,不需要重新定義。編譯器根據模板實現實例聲明和實例定義。
顯示具體化:
對于某些特殊類型,可能不適合模板實現,需要重新定義實現,此時可以使用顯示具體化(explicite specialization)。顯示實例化需重新定義。格式為:
template<> typename function<typename>(argu_list){...};
template<>?class classname<typename>{...};
綜上:
template<> void swap<job>(job &a, job &b) {……};是函數模板的顯式具體化,意思是job類型不適用于函數模板swap的定義,因此通過這個顯式具體化重新定義;也可簡寫作template<> void swap(job &a, job &b);
template void swap<job>(job &a, job &b);是函數模板的一個顯式實例化,只需聲明,編譯器遇到這種顯式實例化,會根據原模板的定義及該聲明直接生成一個實例函數,該函數僅接受job型。否則編譯器遇到模板的使用時才會隱式的生成相應的實例函數。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的c++模板显示实例化,显示具体化,隐式实例化的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。