天天看點

C++模闆的特化詳解(函數模版特殊,類模版特化) 模版與特化的概念 函數模版特化 類模版特化

c++中模闆分為函數模闆和類模闆

函數模闆:是一種抽象函數定義,它代表一類同構函數。

類模闆:是一種更高層次的抽象的類定義。

所謂特化,就是将泛型的東東搞得具體化一些,從字面上來解釋,就是為已有的模闆參數進行一些使其特殊化的指定,使得以前不受任何限制的模闆參數,或受到特定的修飾(例如const或者搖身一變成為了指針之類的東東,甚至是經過别的模闆類包裝之後的模闆類型)或完全被指定了下來。

針對特化的對象不同,分為兩類:函數模闆的特化和類模闆的特化

函數模闆的特化

當函數模闆需要對某些類型進行特化處理,稱為函數模闆的特化。

類模闆的特化

當類模闆内需要對某些類型進行特别處理時,使用類模闆的特化。

特化整體上分為全特化和偏特化

* 全特化

偏特化

就是模闆中的模闆參數沒有被全部确定,需要編譯器在編譯時進行确定。

全特化的标志就是産生出完全确定的東西,而不是還需要在編譯期間去搜尋适合的特化實作,貌似在我的這種了解下,全特化的 東西不論是類還是函數都有這樣的特點,

模闆函數隻能全特化,沒有偏特化(以後可能有)。

模闆類是可以全特化和偏特化的。

template <>然後是完全和模闆類型沒有一點關系的類實作或者函數定義,如果你要說,都完全确定下來了,那還搞什麼模闆呀,直接定義不就完事了? 但是很多時候,我們既需要一個模闆能應對各種情形,又需要它對于某個特定的類型(比如bool)有着特别的處理,這種情形下特化就是需要的了。

全特化的标志:template <>然後是完全和模闆類型沒有一點關系的類實作或者函數定義

偏特化的标志:template

目前的标準中,模闆函數隻能全特化,沒有偏特化

至于為什麼函數不能偏特化,似乎不是因為語言實作不了,而是因為偏特化的功能可以通過函數的重載完成。

函數模闆的特化:當函數模闆需要對某些類型進行特别處理,稱為函數模闆的特化。

例如,我們編寫了一個泛化的比較程式

1

2

3

4

5

6

這個函數滿足我們的需求了麼,顯然不,它支援常見int, float等類型的資料的比較,但是不支援char*(string)類型。

是以我們必須對其進行特化,以讓它支援兩個字元串的比較,是以我們實作了如下的特化函數。

7

也可以

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

函數模版的特化,當函數調用發現有特化後的比對函數時,會優先調用特化的函數,而不再通過函數模版來進行執行個體化。

類模闆的特化:與函數模闆類似,當類模闆内需要對某些類型進行特别處理時,使用類模闆的特化。例如:

這裡歸納了針對一個模闆參數的類模闆特化的幾種類型

一是特化為絕對類型;

二是特化為引用,指針類型;

三是特化為另外一個類模闆。

這裡用一個簡單的例子來說明這三種情況:

也就是說直接為某個特定類型做特化,這是我們最常見的一種特化方式, 如特化為float, double等

52

53

54

55

56

57

58

59

如果期望使用偏特化,那麼

當然,除了t*, 我們也可以将t特化為 const t*, t&, const t&等,以下還是以t*為例:

這種特化其實是就不是一種絕對的特化, 它隻是對類型做了某些限定,但仍然保留了其一定的模闆性,這種特化給我們提供了極大的友善, 如這裡, 我們就不需要對int*, float*, double*等等類型分别做特化了。

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

這就把isequal的參數限定為一種vector類型, 但具體是vector還是vector, 我們可以不關心, 因為對于這兩種類型,我們的處理方式是一樣的,我們可以把這種方式稱為“半特化”。

當然, 我們可以将其“半特化”為任何我們自定義的模闆類類型:

這就是三種類型的模闆特化, 我們可以這麼使用這個compare類:

轉載:http://blog.csdn.net/gatieme/article/details/50953564

繼續閱讀