不能對函數模板進行局部特化,所能做的即使重載它們。
但可以對類模板進行局部特化。
template
template
局部特化的語法類似完全特化,但是他的模板參數列表是非空的。當使用任何(未經修飾的)指針類型來實例化一個Heap時,這個局部特化版將優先於主模板而被采用。進一步而言,當模板實參類型為const char*或char*時,針對const char*和char*的完全特化版本的Heap又將優先於這個局部特化而被采用。
主模板的完全特化或局部特化必須采用與主模板相同數量和類型的實參進行實例化,但它的模板參數列表並不需要具有和主模板相同的形式。對於Heap來說,主模板帶有單個類型名字參數,因此Heap的任何完全特化或局部特化都必須通過采用單個類型名字實參來實例化。
template<>class Heap
//實參,但模板參數列表不同於主模板參數列表,完全特化的模板參數是空的
template
template
對主模板而言,類模板的完全特化和局部特化全然是單獨的實體,他們不從主模板“繼承”任何接口或實現。但通常期望能有和主模板一套相同的接口。
template
class Heap
{
public:
void push(const T& val);
};
可以不針對模板進行特化,只針對模板成員函數特化。
template<>
void Heap
注意,這些函數的接口必須和進行成員特化的模板對的相應接口精確匹配。例如,主模板將push聲明為帶有一個類型為const T &的參數,因此針對const char*的push顯式特化的實參必須為const char* const &。
如果已存在針對一般指針的Heap局部特化,
template
class Heap
{
void push(T*pval);
};
如果這個局部特化已經存在,那麼對push的顯式特化就必須符合該局部特化中push成員接口,因為該函數相當於針對Heap
template<>
void Heap
使用tepename關鍵字可以明確地告訴編譯器,接下來的限定名字是一個類型名字,從而允許編譯器去正確的解析模板。這個關鍵字經常被用在說明嵌套類型中。
一個成員模板就是一個自身是模板的成員。
template
class Slist{
public:
//…
template
};
template
template
SList
while(begin!= end)
push_front(*begin++);
reverse();
}
std配置器中的rebind是一個模板,當如下定義式將會出錯:
template
class SList{
//…
structNode{
//…
};
typedefA::rebind
//…
};
解決辦法:
typedef typename A::template rebind
使用關鍵字template,即等於告訴編譯器,rebind是一個模板,而使用typename則等於告訴編譯器,整個這一堆東西表示的是一個類型名字。
可以從一個特化版本中推導出類型的屬性。讓我們看一個簡單的例子:
template
struct IsInt //T表示一個int
{
enum{result = false};
};
template<>
struct IsInt
{
enum{result= true};
};
有了這個主模板和完全特化版本,就可以在編譯器詢問一個未知的類型是否確實為int:如下
template
void aFunc(X&arg){
//…
…IsInt
//…
}
template
class Seq{
public:
typenameT Elem; //元素類型
typenameT Temp; //臨時對象的類型
size_tsize() const;
//…
};
在編譯期可以查詢到這種嵌入的信息:
typedef Seq
//…
Strings::Elem aString;
見http://blog.csdn.net/walkerkalr/article/details/17287939條款47:請使用traitsclasses表現類型信息