目錄
一、非型別模板引數
1、非型別模板引數的介紹
2、非型別模板引數的使用
二、模板的特化
1、模板特化的概念
2、函式模板的特化
3、類模板的特化
三、模板的分離編譯
1、什么是分離編譯
2、模板的分離編譯
四、模板的優點和缺點
一、非型別模板引數
1、非型別模板引數的介紹
模板引數分為型別別模板引數和非型別模板引數,
- 型別別模板引數:出現在模板引數中,跟在class或者typename后面的引數型別名稱,

- 非型別模板引數:用一個常量作為類或者函式模板的一個引數,在模板中可以將該引數當成常量來使用,

注意:浮點數、類物件、字串不可以做非型別模板引數;非型別的模板引數必須在編譯期就能確認結果,
2、非型別模板引數的使用
型別模板引數在實體化時需要指定型別,非型別模板引數可以在實體化時指定值也可以給定預設值,
template<size_t m,size_t n = 10>
void test()
{
std::cout << m << " " << n<<std::endl;//2 10
}
int main()
{
test<2>();
return 0;
}
二、模板的特化
1、模板特化的概念
使用模板可以撰寫與型別無關的代碼,但是在一些特殊的情況下使用模板可能會得到錯誤的結果,為了解決這些錯誤的結果就需要對模板進行特化,即,在原模板的基礎上對特殊的型別進行特殊化的處理,模板的特化分為函式模板特化和類模板特化,

2、函式模板的特化
函式模板特化的步驟
- 必須有一個基礎的函式模板
- 關鍵字template后面跟一對<>
- 函式名后面跟一對<>,里邊指定需要特化的型別
- 函式形參表: 必須要和模板函式的基礎引數型別完全相同,如果不同編譯器可能會報一些奇怪的錯誤
template<class T>
bool IsEqual(T& left,T& right)
{
return left == right;
}
//函式模板的特化
template<>
bool IsEqual<char*>(char*& left, char*& right)
{
if(strcmp(left, right) > 0)
return true;
return false;
}
注意:一般情況下,函式模板遇到不能處理或者處理有誤的型別時都是直接給出該型別的函式
3、類模板的特化
1)全特化
全特化顧名思義就是將類模板的模板引數串列中全部進行特化,
template<class T1, class T2>
class Data
{
public:
Data()
{
cout<<"Data<T1, T2>" <<endl;
}
private:
T1 _d1;
T2 _d2;
};
//對日期雷模板的類模板引數全部進行特化
template<>
class Data<int, char>
{
public:
Data()
{
cout<<"Data<int, char>" <<endl;
}
private:
int _d1;
char _d2;
};
void TestVector()
{
Data<int, int> d1;
Data<int, char> d2;
}
2)偏特化
偏特化的兩種表現形式
- 對類模板的模板引數串列中的一部分進行特化
// 將第二個引數特化為int
template <class T1>
class Data<T1, int>
{
public:
Data() {cout<<"Data<T1, int>" <<endl;}
private:
T1 _d1;
int _d2;
};
- 對類模板的模板引數串列中的型別特華為指標或參考
//兩個引數偏特化為指標型別
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
Data() {cout<<"Data<T1*, T2*>" <<endl;}
private:
T1 _d1;
T2 _d2;
};
//兩個引數偏特化為參考型別
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:
Data(const T1& d1, const T2& d2)
: _d1(d1)
, _d2(d2)
{
cout<<"Data<T1&, T2&>" <<endl;
}
private:
const T1& _d1;
const T2& _d2;
};
void test2 ()
{
Data<double,int> d1; // 呼叫特化的int版本
Data<int,double> d2; // 呼叫基礎的模板
Data<int *,int*> d3; // 呼叫特化的指標版本
Data<int&,int&> d4(1, 2); // 呼叫特化的指標版本
}
三、模板的分離編譯
1、什么是分離編譯
一個專案由多個源檔案組成,每個源檔案單獨編形成目標檔案,通過鏈接將所有目標檔案鏈接在一起形成可執行檔案,就稱為分離編譯,

2、模板的分離編譯
加入模板的宣告在頭檔案中,定義在源檔案(.cc檔案)中,則對模板進行編譯:

解決方法:模板的宣告和定義放在一起(同一個.hpp檔案中),這樣在預處理階段,編譯器會將頭檔案展開在其他源檔案中,
四、模板的優點和缺點
優點
- 模板復用了代碼,節省資源,更快的迭代開發,C++的標準模板庫(STL)因此而產生
- 增強了代碼的靈活性
缺點
- 模板會導致代碼膨脹問題,也會導致編譯時間變長
- 出現模板編譯錯誤時,錯誤資訊非常凌亂,不易定位錯誤
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/280235.html
標籤:其他
