目錄
出品 | ***:coder梁(id:coder_lt)
前文當中說mjwgjecfta了,模板函式雖然非常好用,但是也存在一些問題。比如有的操作並不是對所有型別都適用的,針對這種情況c++提供了乙個解決方案,就是針對特定型別提供具體化的模板定義。這裡的具體可以理解成型別的具體。
我們來看乙個c++ primer當中的例子,假設現在我們有乙個結構體叫做job:
struct job
對於結構體是可以整體賦值的,所以之前的swap函式對它一樣適用。
template
void swap(t &a, t &b)
但我們現在希望在交換結構體的時候,只是交換salary和floor這兩個字段,把name保持不變。由於我們希望引入邏輯變化,所以直接呼叫swap函式就不可行了。
當然我們可以不用函式模板,直接過載函式:
void swap(job &a, job &b)
由於c++當中規定,非函式模板的優先順序大於函式模板,所以我們在對job結構體呼叫swap函式的時候,會優先使用這個。
除此之外,我們還可以提供乙個具體化的模板函式:
template <> void swap (job &a, job &b)
這個函式的寫法看起來有些特殊,我們在函式型別之前加上了template <>,在函式名後面又跟上了。它表示的是這是乙個函式模板的顯式具體化,也可以理解成為之前的函式模板提供乙個job型別的版本。c++當中規定顯式模板函式的優先順序高於普通模板函式。
關於函式模板,還有乙個很重要的概念,就是例項化。
我們在編寫**時,如果只是編寫了函式模板本身,編譯器是不會為我們生成函式的定義的。當編譯器使用模板為特定的型別生成函式定義時,就會得到乙個模板的例項。這個概念有點像是python裡的元類,元類的例項是另外乙個類。
比如我們定義了乙個函式模板:
template
void swap(t &a, t &b)
當我們呼叫它,傳入兩個int型別的時候,編譯器就會生成乙個例項,這個例項使用的型別是int。當我們使用double型別的引數又一次呼叫的時候,編譯器會繼續生成double型別的例項。這個生成例項的過程是不可見的,所以被稱為隱式例項化。
在早年的c++版本當中只支援隱式例項化,但現在c++允許顯示例項化。也就意味著我們可以手動命令編譯器建立特定的例項,比如swap()。語法是通過<>宣告指定模板型別,並且在宣告之前加上關鍵字template,如:
template void swap(int, int);
這個語法看起來和顯式具體化非常相似,顯式具體化的寫法是:
template<> void swap(int &, int &);
template<> void swap(int &, int &);
看起來非常相似,但是含義是完全不同的。顯式具體化的含義是對於某特定型別不要使用原模板生成函式,而應專門使用指定的函式定義。而顯式例項化是使用之前的模板函式的定義的,只不過是手動觸發編譯器建立函式例項而已。
對了,我們不能同時在乙個檔案中,使用同一種型別的顯式例項化和顯式具體化,這會引起報錯。
我們如果死記顯式例項化的宣告,的確很容易和具體化混淆。但我們可以在**當中直接使用,直接使用的形式則要簡單許多,只需要通過<>表明型別即可。
例如:template
t add(t a, t b)
int main() 程式設計客棧 程式設計客棧
在上面這段**當中,我們通過給add函式加上了來手動建立了乙個接受double型別的函式。需要注意的是,我們傳入的a是乙個int型別。所以編譯程式設計客棧器會執行強制型別轉換,將它轉換成double傳入。
C 函式模板的顯式具體化
功能 c 模板的顯式具體化練習。常規模板 add加法模板,採用顯式具體化模板方式,具體化乙個複數相加的add函式。總結 顯式具體化是針對常規模板進行的,因此必須與常規模板的定義格式相符合。如下程式所示,除any型別可以用乙個具體化的c 型別 替換外,其它應該保持與常規模板一致,否則可能不能進行編譯 ...
C 函式模板的顯式具體化
我們知道可以利用函式模板來處理不同的資料型別,然而函式模板對於某些資料型別並不能處理,具有一定的侷限性。那麼應該如何解決該侷限性呢?例如經典的資料交換函式swap template typename t void swap t a,t b 我們可能希望利用上述的函式模板實現不同型別資料的交換,然而對...
C 函式模板的顯式具體化
在c 中,我們可以使用函式模板來增加 的復用性,但是並不是所有的型別都可以呼叫函式函式模板來處理,如陣列和結構體資料型別。這就是函式模板的侷限性。struct job 交換兩個這種結構的內容,原來的模板使用以下 進行交換 temp a a b b temp 由於c 允許將乙個結構賦給另乙個結構,因此...