C 模板與特化

2021-08-20 17:31:11 字數 2914 閱讀 9318

模板,template,是一種將資料型別參化的工具,提供了一種將**與資料類相脫離的機制,即**不受具體的資料的型別的影響,從而為c++提供了泛型程式設計的方式,減少冗餘**的同時依然可以提供型別安全。模板分為兩種:

特化,specialization,是針對某個特定的型別,在模板定義時給出不同一般資料型別的邏輯實現。然而在使用的時候,這個特殊性完全被遮蔽,我們仍然只需要按照模板來使用,編譯器會根據模板的**設定,針對特別的資料型別呼叫我們設定的特別的**邏輯。

簡單點來說,已有的模板的形參型別不受任何的限制,什麼引數型別都可以,但是考慮到實際情況中,可能存在某些特定的資料型別不滿足當前的泛型模板的**邏輯,就需要針對特定的資料型別,對模板進行新的**邏輯的設計,就是特化。

針對特化的物件不同,可以分為兩類:

針對特化的引數個數,可以分為兩類:

注意:

類模板與函式模板的宣告方式是一樣的,在類或函式定義之前宣告模板引數列表,示例**如下:

// 類模板

template

class a;

// 函式模板

template

t1 max(const t1 lhs, const t2 rhs)

通過全特化乙個模板,可以對乙個特定引數集合,自定義當前的模板。類模板與函式模板都可以全特化。全特化的模板引數列表是空的:<>,並應給出「模板實參」列表。示例**如下:

// 全特化類模板

template

<> //告訴編譯器這是乙個特化的模板。

class a;

// 函式模板

template

<> //告訴編譯器這是乙個特化的模板。

int max(const

int lhs, const

double rhs)

注意:

這裡對於函式模板,由於上述**中,max是有形參列表的,所以編譯器是可以通過函式簽名:int max(const int, const int),來推導出max是函式模板:t1 max(const t1, const t2),的特化。但如果函式沒有形參列表呢?這時如果讓編譯器自動推導,使用隱式例項化的方法,就會報錯。舉個例子:

template

void f()

template

<>

void f()

這時,編譯器會報錯:

error: no function

template matches function

template specialization 'f'

所以,為了解決這種問題,我們需要顯示例項化,或者說顯示特化函式模板:

template

void f()

template

<>

void f()

類似於全特化,偏特化也是為了給自定義乙個引數集合的模板,但偏特化後的模板需要進一步的例項化才能形成確定的簽名。 值得注意的是函式模板不允許偏特化,這一點在effective c++: item 25中有更詳細的討論。 偏特化也是以template來宣告的,需要給出剩餘的」模板形參」和必要的」模板實參」。示例**如下:

template class a;
函式模板不支援偏特化,但是可以通過過載實現類似的需要:

template

void f(){}

//error

template

void f(){}

//right

template

// 注意:這裡模板宣告不一樣

void f(){} // 注意:這裡沒有"模板實參"

之前介紹的特化型別,仔細觀察就不難發現,主要是特化為絕對型別。但其實還可以將型別特化為指標或引用型別,或者特化為另乙個類模板。

template

struct iterator_traits ;

// specialize for _tp*

template

struct iterator_traits<_tp*> ;

// specialize for const _tp*

template

struct iterator_traits ;

還可以將t特化為const t*,t&,const t&等。以t *為例,**如下:

// specialize for t*

template

class compare

};

這其實是第二種方式的擴充套件,其實也是對型別做了某種限定,而不是絕對化為某個具體型別,示例**如下:

// specialize for vector

template

class compare>

}return

true;

}};

這就把isequal的引數限定為一種vector型別, 但具體是vector還是vector, 我們可以不關心, 因為對於這兩種型別,我們的處理方式是一樣的,我們可以把這種方式稱為「半特化」。

當然, 我們可以將其「半特化」為任何我們自定義的模板類型別,示例**如下:

// specialize for any template class type

template

struct specializedtype

;template

class compare< specializedtype>

};

C 模板 特化 與 偏特化

c 模板作為乙個泛化手段,與之相對,對於某種特殊場合,可能要對模板進行相應的特化,偏特化處理。模板為什麼要特化,因為編譯器認為,對於特定的型別,如果你能對某一功能更好的實現,那麼就該聽你的。模板分為類模板與函式模板,特化分為全特化與偏特化。全特化就是限定死模板實現的具體型別,偏特化就是如果這個模板有...

c 模板特化與區域性特化

c 模板特化與區域性特化 全部特化 templateclass test template class test 通過上面的例子可以看出,可以針對型別int,定義乙個新的處理。當外部使用時,穿進來的型別是int的話,就會進入到特化定義的類裡。區域性特化種類1 把模板型別列表裡,部分的型別,特化。te...

C 模板 全特化與偏特化

模板 模板定義 模板就是實現 重用機制的一種工具,它可以實現型別引數化,即把型別定義為引數,從而實現了真正的 可重用性。模版可以分為兩類,乙個是函式模版,另外乙個是類模版。大白話 c 是一門強型別語言,編寫一段通用的邏輯,可以把任意型別的變數傳進去處理,通過把通用邏輯設計為模板,擺脫了型別的限制,極...