C 函式模板的隱式例項化 顯式例項化與顯式具體化

2021-08-11 12:27:32 字數 2688 閱讀 7677

一、什麼是例項化和具體化?

為進一步了解模板,必須理解術語例項化和具體化。

(1)、例項化:在程式中的函式模板本身並不會生成函式定義,它只是乙個用於生成函式定義的方案。編譯器使用模板為特定型別生成函式定義時,得到的是模板例項。這即是函式模板的例項化。

而函式模板例項化又分為兩種型別:隱式例項化和

顯式例項化

例如:

template < typename t >

void swap( t &a, t &b )

int main(void)

可以發現,在主函式中有兩種swap函式呼叫。

第乙個swap(a, b)導致編譯器自動識別引數型別生成乙個例項,該例項使用int型別,此為隱式例項化。

而第二個swap(a, b),直接命令編譯器建立特定的int型別的函式例項,用<>符號指示型別,此為顯式例項化。

(2)、具體化:即顯式具體化,與例項化不同的是,它也是乙個模板定義,但它是對特定型別的模板定義。顯式具體化使用下面兩個等價的宣告之一:

template <> void swap(int &, int &);
template <> void swap(int &, int &);
可以發現,顯式具體化宣告在關鍵字template後包含<>。上面宣告的意思是"不要使用swap()模板來生成函式定義,而應使用專門為int型別顯式地定義的函式的定義"。這些原型必須有自己的函式定義。

在這裡,有人可能要說了:」明明可以通過隱式例項化自動生成int型別的函式定義,為何還要弄出乙個顯式具體化來弄出另外乙個模板呢?這不是多此一舉嗎?」

我要解釋一下,顯式具體化的主要用途!而在介紹用途之前,我們先來了解一下普通函式模板的侷限性。

二、模板的侷限性

假設有如下模板函式:

template void fun(t a, t b)

通常,**假定可執行哪些操作。例如,下面的**假定定義了賦值。

a = b;
但是如果t為陣列,這種假設將不成立!

同樣,下面的語句假設定義了<

if ( a > b )
但如果t為結構,則該假設便不成立!

另外,為陣列名定義了運算子 > ,但由於陣列名是常量位址,因此它比較的是陣列的位址,而這並不是我們所期望的操作。下面的語句假定為型別t定義了乘法運算子,但如果t為陣列、指標或結構,這種假設便不成立:

t c = a * b;
總之,編寫的模板函式很可能無法處理某些型別。通常在c++中有一種解決方案是:運算子過載,以便能將其用於特定的結構或類。就是說乙個類過載了運算子+之後,使用運算子+的模板便可以處理過載了運算子+的結構。

但是,還有另外一種解決方案:為特定型別提供具體化的模板定義(這就是顯式具體化的主要用途)。

三、顯式具體化

假定定義了如下結構:

struct job

另外,假設希望能夠交換兩個這種結構的內容。原來的模板使用下面的**來完成交換:

temp  =  a;

a = b;

b = temp;

由於c++允許將乙個結構賦給另乙個結構,因此即使t是乙個job結構,上述**也可適用。然而,如果只想交換salary和floor成員,而不交換name成員,則需要使用不同的處理**。但swap() 的引數將保持不變(兩個job結構的引用),因此無法使用模板的過載來提供其他**(模板過載,模板的引數列表必須不同)。這時,就得用顯式具體化來實現這個需求。

上面已經介紹過顯式具體化的宣告方式,我們直接通過**例項來看一下:

#include using namespace std;

//job結構

struct job

;//普通交換模板

template void swap(t &a, t &b)

//job型別的顯式具體化模板

template <> void swap(job &j1, job &j2)

int main(void)

; job lisi = ;

cout << "inta = " << inta << " inta = " << intb << endl;

cout << zhangsan.name << " , " << zhangsan.salary << " , " << zhangsan.floor <

執行截圖:

在程式執行時匹配模板時,遵循的優先順序是:

具體化模板優先於常規模板,而非模板函式優先於具體化和常規模板。

函式模板的隱式例項化和顯式例項化

一.隱式例項化 1 include 2 include 3 using namespace std 4 5 template 6 bool compare t a,t b 7 13 14 int main 15 以上 compare 100,220 compare 120,99 compare 99...

C 模版 顯式例項化 顯式具體化 隱式例項化

helloword的部落格 函式模板是c 新增的一種性質,它允許只定義一次函式的實現,即可使用不同型別的引數來呼叫該函式。這樣做可以減小 的書寫的複雜度,同時也便於修改 注 使用模板函式並不會減少最終可執行程式的大小,因為在呼叫模板函式時,編譯器都根據呼叫時的引數型別進行了相應例項化 下面來看看函式...

C 模版 顯式例項化 顯式具體化 隱式例項化

helloword的部落格 函式模板是c 新增的一種性質,它允許只定義一次函式的實現,即可使用不同型別的引數來呼叫該函式。這樣做可以減小 的書寫的複雜度,同時也便於修改 注 使用模板函式並不會減少最終可執行程式的大小,因為在呼叫模板函式時,編譯器都根據呼叫時的引數型別進行了相應例項化 下面來看看函式...