模板-1-模板類的特化

類模板的特化

  • 語義: 代表該模板類在特殊的類型下具備不一樣的行爲.函數

    • 類的定義,應該與模板類放入一個頭文件中,告知編譯器該特化類的存在;spa

    • 類成員的定義,應該放入源文件中.該特化類就與普通類同樣,是一個實實在在存在的實體.code

  • 語法: 仍依'template<>'代表該類是一個模板,但被特化的類;get

    • 類外定義特化類的成員時,不該添加'template<>'標記.編譯器

template<>
class    類名<特化類的模板實參表>{
    /* 特化類的定義 */
};

  • 對特化類的要求: 類名與模板類一致便可,其他沒有任何限制:特化類能夠具備不一樣的成員集合,特化類能夠具備不一樣的父類....編譯

template<typename Type1,typename Type2>
class   X{
public:
    void    print(){ Println("模板類: Type1: %s\tType2: %s",getTypeName(Type1),getTypeName(Type2)); }
};

template<>
class   X<int,double>{
public:
    void    print();
    void    test(){}
};

/* 不要添加'template<>'標記 */
void    X<int,double>::print(){ Println("特化類: Type1: int\tType2: double"); }

int main(int argc,char *argv[]){
    X<double,double>    dd;
    dd.print();
//  dd.test();  /* 錯誤!X<double,double>不存在test()成員函數. */

    X<int,double>       id;
    id.print();
    id.test();  /* 只要X<int,double>中才存在test()成員函數 */
}

特化成員而不特化類

  • 語義: 代表該模板類在指定的模板實參下,其某些成員具備不一樣的行爲.模板

  • 語法: 見下面的例子. class

    • 特化成員的聲明應該與模板類放在同一個頭文件中.test

    • 若是成員特化後是一個實實在在的函數,則應該放入源文件中;不然應該放入頭文件中.語法

/* TestTem.h --- 模板類及其布特化成員的聲明 */
#define     getTypeName(type)       typeid(type).name()
#define     PrintType(type) Println(#type ": %s",getTypeName(type));

template<typename Type1>
struct TestTem {
    template<typename Type2>
    void    func2();
    void    func1();
};

/* 成員func1的特化聲明.此時func1是一個實實在在的函數 */
template<>
void    TestTem<float>::func1();

/* 模板成員func2的特化聲明,此時僅特化了一部分.因此特化後的func2還是模板. */
template<> template<typename Type2>
void    TestTem<float>::func2();

/* 模板成員 func2 的特化聲明,此時進行了所有特化,func2也是一個實實在在的函數. */
template<> template<>
void    TestTem<float>::func2<double>();

/* --- TestTem成員定義 ---- */
template<typename Type1>
void    TestTem<Type1>::func1(){
    Println("模板: %s",getTypeName(Type1));
}
template<typename Type1> template<typename Type2>
void    TestTem<Type1>::func2(){
    Println("模板: %s\t%s",getTypeName(Type1),getTypeName(Type2));
}

/* --- 特化函數func2的定義 --- */
template<> template<typename Type2>
void    TestTem<float>::func2(){ Println("1特化: double\t%s",getTypeName(Type2)); }

/* TestTem.cc --- 特化成員的定義 */
/* 成員func1的特化聲明.此時func1是一個實實在在的函數 */
template<>
void	TestTem<float>::func1(){ Println("特化: int"); }

/* 模板成員 func2 的特化聲明,此時進行了所有特化,func2也是一個實實在在的函數. */
template<> template<>
void	TestTem<float>::func2<double>(){ Println("2特化: float\tdouble"); }

類模板的部分特化

  • 部分特化的類仍然是模板,能夠與其特化類具備徹底不一樣的成員集合,父類..

#define		TypeName(type)		typeid(type).name()
#define 	PrintType(type) Println(#type ": %s",TypeName(type));

template<typename Type1,typename Type2,typename Type3>
struct	X{
	void	print(){ Println("模板: %s\t%s\t%s",TypeName(Type1),TypeName(Type2),TypeName(Type3)); }
};

/* 是其模板類模板形參表的子集 */
template<typename Type2>
struct	X<int,Type2,double>{/* 此時 Type1=int,Type3=double */
	void	print(){ Println("特化: i\t%s\td",TypeName(Type2)); }
};

X<double,double,double>    x;    /* 使用模板類,此時 Type1=Type2=Type3=double */
X<int,double,double>    x1    /* 使用部分特化類,此時 Type1=int,Type2=double,Type3=double */
相關文章
相關標籤/搜索