C 泛型程式設計 五 模版過載與特例化

2021-10-08 20:14:55 字數 2996 閱讀 9043

前文回顧:

c++ 泛型程式設計(一) 基本概念

c++ 泛型程式設計(二) 函式模版

c++ 泛型程式設計(三) 模版實參推斷

c++ 泛型程式設計(四) 類模板

函式模版可以被另乙個模版或者乙個普通非模版函式重做;名字相同的函式必須具有不同數量或者型別的引數。

根據引數推斷只有乙個版本是可行的,則選擇該版本

都是可行的,匹配更精確的版本

都是精確匹配,選擇特化版本

普通函式可以匹配,選擇普通函式

通過空模板實參列表限定只匹配模板

概念①.特例化:模板,代表了一種泛化的語義,與之相對的就是特化語義。特例化,使得我們能為某些特定的型別專門提供乙份特殊實現;特例化本質上是我們頂替了編譯器的工作,我們幫編譯器做了型別推導。

②.全特化:本質上是乙個例項,我們必須為模版中每個引數都提供實參。使用關鍵字 template 加空尖括號對 <> 定義。

③.偏特化:本質上還是乙個模板,只是原來模板的乙個子集。

函式模版特例化

①.定義

函式模版的不存在偏特化,偏特化即為模版的過載。

templatet add(t a, t b)	

//特例化版本,template<>

template< >

double add(double a, double b)

//過載版本,還是模版

templatet1 add(t1* a, t1* b)

②.標頭檔案

模版及其特例化版本應該宣告在同乙個標頭檔案中,所有同名模版的宣告應該放在特例化版本之前。

類模版特例化

①.類模版全特化

跟函式模板一樣,全特化是乙個例項,當編譯器匹配時會優先匹配引數一致的例項。

//類模版

templateclass a

t add(t x)

privete:

t t;

};//全特化

template< >

class a// 乙個全特化的模板類a

char* add(char* x)

private:

char* t;

};

②.偏特化-指定部分引數

template// 普通版本,有兩個模板引數

class b ;

template// 偏特化版本,指定其中乙個引數,即指定了部分型別

class b;

③.偏特化-指定引數形式

template// 普通版本

class b ;

template//這個偏特化版本只接收指標型別的模板實參

class b;

③.特例化成員

我們也可以只特例化特定成員函式而不是特例化整個模版。

//類模版

template class foo

void bar(){}

private:

t mem;

}template<>//全特化

void foo::bar()//特例化 foo的乙個成員

概念①.可變引數模版:就是可以接受可變資料引數的模版函式和模版類,即引數數量、以及每個引數的型別都未知且各不相同。

②.引數包:可變數目的引數稱為引數包,用省略號來表示乙個包。

③.模版引數包:表示零個或者多個模版引數,用 typename… 宣告。

④.函式引數包:表示零個或者多個函式引數。

⑤.sizeof…:獲取引數包內引數的數量

⑥:pattern…:以某一模式展開引數包,用省略好觸發擴充套件操作。

定義可變引數模版

可變引數模版通常是遞迴的,引數包args …在展開的過程中遞迴呼叫自己,沒呼叫一次引數包中的引數就會少乙個, 直到所有引數都展開為止。

//args 是乙個模版引數包,表示零個或者多個模版型別的引數

//rest 是乙個函式引數包,表示零個或者多個函式引數

template//函式每次分解出乙個 val,剩下的再構成乙個包

//模版引數擴充套件模式:const args &,對包中每個引數取相同的操作

//等價於:void print(const t &val, const t1 &t1,const t2 &t2,const t3 &3,const t4 &t4,...)

void print(const t &val, const args &... rest)

//遞迴終點

void print() {}

**引數包

可變引數函式也可以將它的引數**給其他函式。模版引數包擴充套件為乙個右值引用的列表,函式引數擴充套件為乙個用 forward 保持型別不變的乙個列表。

template//模版引數擴充套件模式:args&&,擴充套件為右值引用列表

《Effective C 》模版與泛型程式設計

item41 了解隱式介面和編譯期多型 縱使你從未使用過templates,應該不陌生 執行期多型 和 編譯期多型 之間的差異。因為它類似於 哪乙個過載函式該被呼叫 發生在編譯期 和 哪乙個virtual函式應該被繫結 發生在執行期 之間的差異。加諸於template引數身上的隱式介面,就像加諸於c...

C 16章 模版與泛型程式設計

template 模版引數列表,用逗號分割多個模版引數,且模板引數列表不可能空。引用避免了引數賦值 int compare const t v1 const t v2 template 模版引數列表,用逗號分割多個模版引數 int compare const char v1 u const char...

C 模板與泛型程式設計

1 物件導向程式設計總是以顯式介面和執行時多型解決問題。模板及泛型世界不同,在此世界中顯式介面和執行時多型仍然存在,但重要性降低,反倒是隱式介面和編譯器多型移到前頭。執行時多型和編譯時多型 前者表示哪乙個虛函式該被繫結,後者表示哪乙個過載函式該被呼叫。顯式介面由函式的簽名式 函式名稱 引數型別 返回...