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

C++模板實戰4:模板特化

編輯:C++入門知識

模板設計的目的就是為了通用,但是某些情形下也有特殊情形獨立於通用規則,因此模板需要針對特殊情形進行特化。

1 類模板的特化,在模板類名自後<>內寫上特化的類型名,其中<>這部分叫做匹配式,如下:

template//通用模板
void show();

template<>//特化模板的模板參數,這裡不再需要參數故為空,<>不能省略
void show();//特化模板,其中叫匹配式
特化規則如下:

1) 匹配式寫在模板類名之後,用<>包住,即使模板特化沒有引入新的類型參數,<>也不能省略

2) 匹配式內用逗號隔開的項目列表,如前面的,且項目數目必須和通用模板參數個數一致,也就是這裡通用模板參數是T、N,所以特化時不能類似於show

3) 匹配式中各項目類型須與通用模板參數類型一致

4) 匹配式項目可以是具體的模板參數值,也可以是特化成具體的類型

5) 當匹配式項目是類型模板參數時,與函數變量類似,模板參數也可以用*、&、const、volatile等修飾

實例如下:

//用於模板型模板參數的模板
template struct S1;

//模板通例,有三個模板參數,分別是類型參數,非類型參數及模板型參數
template class SP>//通用模板
struct S;

//特例1,可匹配S
template class SP>
struct S;

//特例2,可匹配S<任意有const修飾的類型, 任意整數, S1>
template class SP>
struct S;

//特例3,完全特例,只能匹配S
template<>//此例是完全特化,其余是部分特化
struct S;

//特例4,以模板實例作為類型參數值。匹配S, 10, S1>
template
struct S, 10, S1>;

//特例5,錯誤!匹配式項目數與通例參數數不一致
// template class SP, typename TT>
// struct S;

//特例6,錯誤!匹配式項目類型與通例參數類型不同
// template
// struct S;

//特例7,錯誤!模板型參數SP與通例中SP類型不一致
// template class SP>
// struct S;

2 類模板匹配按照最佳匹配原則進行匹配,實例如下:

#include 

template
struct S
{
    std::string id() {return "General";}
};

//特例1,約束第三參數必須為char
template
struct S
{
    std::string id() {return "Specialization #1";}
};

//特例2,約束第二、第三參數必須均為char
template
struct S
{
    std::string id() {return "Specialization #2";}
};

//特例3,約束第一參數必須為int,且第二、第三參數相同
template
struct S
{
    std::string id() {return "Specialization #3";}
};

int main()
{
    using namespace std;
    cout << S().id() << endl; //General
    cout << S().id() << endl;       //Specialization #3
    cout << S().id() << endl;      //Specialization #1
    cout << S().id() << endl;    //Specialization #2
    //cout << S().id() << endl;   //可匹配2、3,有歧義
}

3 函數模板特化與重載函數,當函數模板完全特例化後和重載函數類似,但是模板實例化代碼是編譯器在編譯期展開的所以是內聯的。多個模板實例或用相同類型的普通函數混合在一起的時候函數的匹配規則如下:

1) 最佳匹配原則,按照實參和形參的匹配程度最優選擇

2) 普通函數優先於模板實例

3) 模板實例間特化程度高的優先級高

實例如下:

#include
using namespace std;
template
void fun(T x,N y){
    cout<<"#1 "<
void fun(T x,int y){
    cout<<"#2 "<//函數模板不允許部分特化,只能完全特化
//void fun(T x,char y){
//    cout<<"#3 "<<<
void fun(char x,char y){//完全特化
    cout<<"#4 "<
void fun(double x,double y){
    cout<<"#5 "<(1,2);//通用模板
    fun(1,'a');//通用模板
    fun<>('a','b');//指定了使用特化版本fun
    fun('a','b');//普通函數fun(char x,char y),當沒有這個普通函數時調用完全特化版本
    fun(3.14,3.14156);//完全特化版本
    fun(true);//普通函數fun(bool x)
    return 0;
}
程序輸出:

#1 1 2
#1 1 a
#4 a b
#7 a b
#5 3.14 3.14156
#6 1

4 模板特化用於編譯期條件判斷,實例如下:

#include 

template
void print()
{
  print();
  std::cout << i << std::endl;
}

//特例,終止遞歸。
template<>
void print<1>()
{
  std::cout << 1 << std::endl;
}

int main()
{
  print<100>();//在編譯期展開相當於100條輸出語句
}
程序輸出:

1

2

....

100


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