剖析C 模板(中)

2021-04-07 08:23:34 字數 3324 閱讀 3425

函式模板中的型別歸納 

乙個非常簡單但很有用的例子:

//: :arraysize.h 

// uses template type induction to 

// discover the size of an array 

#ifndef arraysize_h 

#define arraysize_h 

template

int asz(t (&)[size])  

#endif // arraysize_h ///:~ 

沒有使用sizeof()操作,卻能在編譯階段指出陣列的大小,你可以有更多簡明的方法來計算編譯時陣列的大小。 

//: c03:arraysize.cpp 

// the return 

value of the template function 

// asz() is a compile-time constant 

#include 

"../arraysize.h

"int main() 

///:~ 

當然,程式正常執行的前提是:陣列在定義時就已經給出了大小。 

取得乙個已經例項化的函式模板的位址 

有很多地方,你都需要取得函式入口位址,例如,你可能有乙個函式,它的引數是乙個指向另乙個函式的指標,當然了,

這個被指的函式有可能是從乙個模板中生成的,所以,你需要一種方法來取得這樣的函式位址。

//: c03:templatefunctionaddress.cpp 

// taking the address of a function generated 

// from a template. 

template void f(t*) {} 

void h(void (*pf)(int*)) {} 

template 

void g(void (*pf)(t*)) {} 

int main() 

///:~ 

這個例子講述了許多的不同的主題。首先,即使你在使用模板,型別必須匹配——函式h()取了乙個指向函式指標,這個函

授接受int型別的引數返回void型別。而這正是f的特點。第二,需要函式指標作為引數的這個函式本身也可以是乙個模板,就

像g一樣。在main()函式中,你可以看到型別歸納同樣也在這裡工作。第一次呼叫h()明確的給出了模板引數f,但是從h()中看

到它僅僅處理使用int型變數做引數的函式的函式指標,那一部分可以由編譯器來歸納。g()的使用還要有意思些,因為這裡有兩

個模板要使用。編譯器不能歸納出來這個型別,也就什麼都不會做,但如果f和g都賦成int,其它的對編譯器來說也就好辦了。 

模板中的成員類 

向stl系列中應用函式

假設你想使用乙個stl系列的容器,並且向容器中包含的所有物件應用乙個函式,我之所以這樣說是因為乙個vector可以包

含各種型別的物件,你需要乙個函式可以同vector協同工作,處理它所包含的各種物件:

// 0 arguments, any type of return 

value:  } 

// 乙個引數,返回值不定  } 

//兩個引數,返回值不定 

template 

a1 a1, a2 a2)  } 

// 諸如此類, 傳遞最多的類似的引數 ///:~ 

定位向各個物件套用這個函式。 

候,考慮到iterator的特殊性,我們也只能把它應用到stl系列中了(別忘了,我們必須使用iterator)。 

模板,這些引數可以為任何型別,唯一的限制是:這不是超級模板可以為你建立出新的模板。 

//: c03:gromit.h 

// the techno-dog. has member functions 

// with various numbers of arguments. 

#include 

class gromit 

void speak(int) 

char eat(float) 

int sleep(char, double) 

void sit(void) {} 

}; ///:~ 

#include 

"gromit.h

"#include 

"#include 

#include 

using namespace std; 

int main() 

///:~ 

的程式而奮鬥所為達到的目標吧:無需知道細節,只需知道實現自己的目標即可。 

模板的模板 

//: c03:templatetemplate.cpp 

#include 

#include 

#include 

using namespace std; 

// as long as things are ******, 

template

void print1(c& c) 

// template-template argument must 

// be a class; cannot use typename: 

templateclass c> 

void print2(c& c) 

int main() 

///:~ 

成員函式模板 

新的容器,把我們的新函式加到這個容器中去。當然,為了具有最好的適應性,我們將使用stl系列的容器,並且,必須使用模

板的模板來做這項工作,告訴編譯器乙個模板引數是即上是乙個模板,而它自身作為乙個型別引數也可以被初始化。看下面: 

// member function templates 

templateclass seq> 

public: 

// 0 arguments, any type of return 

value:  } 

// 1 argument, any type of return 

value:  } 

// 2 arguments, any type of return 

value: 

a1 a1, a2 a2)  } 

}; ///:~ 

()和end()也是新類的成員函式了,這一切看上去都那麼清晰,明了。然而,基本的**仍是一樣的

#include 

"gromit.h

"#include 

"#include 

#include 

using namespace std; 

int main() 

///:~ 

C 深度剖析教程38 類模板深度剖析

類模板可以定義任意多個不同的型別引數 類模板可以被特化 類模板的特化型別 看 include include using namespace std template typename t1,typename t2 class test template typename t1,typename t...

類模板深度剖析

多引數類模板 類模板可以定義任意多個不同的型別引數 template class test 使用上述的類模板 testt 類模板可以被特化 即特殊化 指定類模板的特定實現 部分型別引數必須顯示指定 根據型別引數分開實現類模板 template class test 上面的類模板可以被特化為 temp...

類模板深度剖析

類模板可以定義任意多個不同的型別引數 類模板可以被特化 指定類模板的特定實現 部分型別引數必須顯示指定 根據型別引數分開實現類模板 類模板的特化型別 部分特化 用特定規則約束型別引數 完全特化 完全顯示指定型別引數 類模板特化注意事項 特化只是模板的分開實現 本質上是同乙個類模板 特化類模板的使用方...