程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++必知必會(5)

C++必知必會(5)

編輯:C++入門知識

條款47模板局部特化

不能對函數模板進行局部特化,所能做的即使重載它們。

但可以對類模板進行局部特化。

template class Heap; //主模板

template classHeap{…}; //局部特化

局部特化的語法類似完全特化,但是他的模板參數列表是非空的。當使用任何(未經修飾的)指針類型來實例化一個Heap時,這個局部特化版將優先於主模板而被采用。進一步而言,當模板實參類型為const char*或char*時,針對const char*和char*的完全特化版本的Heap又將優先於這個局部特化而被采用。

主模板的完全特化或局部特化必須采用與主模板相同數量和類型的實參進行實例化,但它的模板參數列表並不需要具有和主模板相同的形式。對於Heap來說,主模板帶有單個類型名字參數,因此Heap的任何完全特化或局部特化都必須通過采用單個類型名字實參來實例化。

template<>class Heap{…}; //完全特化,帶有單個類型名字模板

//實參,但模板參數列表不同於主模板參數列表,完全特化的模板參數是空的

template classHeap{…}; //局部特化,帶有單個類型實參,模板參//數列表也可以帶有單個類型名字參數,但不是必須的,如下

template classHeap{…}; //局部特化,帶有單個類型實參, 但該參數必須是一個具有n個類型為T的元素的數組

條款48類模板成員特化

對主模板而言,類模板的完全特化和局部特化全然是單獨的實體,他們不從主模板“繼承”任何接口或實現。但通常期望能有和主模板一套相同的接口。

template

class Heap

{

public:

void push(const T& val);

};

可以不針對模板進行特化,只針對模板成員函數特化。

template<>

void Heap::push(constchar* const &pval){…}

注意,這些函數的接口必須和進行成員特化的模板對的相應接口精確匹配。例如,主模板將push聲明為帶有一個類型為const T &的參數,因此針對const char*的push顯式特化的實參必須為const char* const &。

如果已存在針對一般指針的Heap局部特化,

template

class Heap

{

void push(T*pval);

};

如果這個局部特化已經存在,那麼對push的顯式特化就必須符合該局部特化中push成員接口,因為該函數相當於針對Heap進行實例化所得的結果。所以,顯式特化現在必須聲明為:

template<>

void Heap::push(const char* pval){…}

條款49利用typename消除歧義

使用tepename關鍵字可以明確地告訴編譯器,接下來的限定名字是一個類型名字,從而允許編譯器去正確的解析模板。這個關鍵字經常被用在說明嵌套類型中。

模板50成員模板

一個成員模板就是一個自身是模板的成員。

template

class Slist{

public:

//…

template Slist(In begin, In end);

};

template

template

SList::SList(In begin, In end) :head_(0){

while(begin!= end)

push_front(*begin++);

reverse();

}

條款51 采用template消除歧義

std配置器中的rebind是一個模板,當如下定義式將會出錯:

template>

class SList{

//…

structNode{

//…

};

typedefA::rebind::other NodeAlloc; //語法錯誤!

//…

};

解決辦法:

typedef typename A::template rebind::otherNodeAlloc;

使用關鍵字template,即等於告訴編譯器,rebind是一個模板,而使用typename則等於告訴編譯器,整個這一堆東西表示的是一個類型名字。

條款52針對類型信息的特化

可以從一個特化版本中推導出類型的屬性。讓我們看一個簡單的例子:

template

struct IsInt //T表示一個int

{

enum{result = false};

};

template<>

struct IsInt //除非是一個int

{

enum{result= true};

};

有了這個主模板和完全特化版本,就可以在編譯器詢問一個未知的類型是否確實為int:如下

template

void aFunc(X&arg){

//…

…IsInt::result…

//…

}

條款53 嵌入的類型信息

template

class Seq{

public:

typenameT Elem; //元素類型

typenameT Temp; //臨時對象的類型

size_tsize() const;

//…

};

在編譯期可以查詢到這種嵌入的信息:

typedef Seq Strings;

//…

Strings::Elem aString;

條款54traits

見http://blog.csdn.net/walkerkalr/article/details/17287939條款47:請使用traitsclasses表現類型信息

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved