模板引數,模板分離編譯
模板的形參:
1.型別形參:
template<class T>
void h(T a)
{//……}
- 型別形參是指:class T/ typename T中的T,型別形參的名字由使用者自己定義,模板的形參(T)表示一個未知的型別。
- 模板型別形參可以作為型別說明符用在模板中的任何地方,與內建型別/類型別的使用方式完全相同,即可以用於指定返回型別,宣告變數等地方
- 不能為同一個的模板型別形參指定兩種不同的型別,比如:
template<class T>
void h(T a,T b)
{}
void test()
{
h(1,1.2);
}
這樣的呼叫方式會出錯,因為該語句給同一模板形參T指定了倆種不同的型別(int,double)
- 無論時模板函式,還是模板類都不能給同一個模板型別指定倆者不同型別的形參
2.非型別模板形參:
- 模板的非型別形參也就是內建型別形參:如:template<class T,int a>class B{},其中int a就是非型別模板形參
- 非型別模板形參在模板定義的內部是常量值
- 非型別模板形參只能是整型,指標,引用,不能使用double,string等
- 呼叫非型別模板形參的實參只能是一個常量表示式,即他必須能在編譯時計算出結果
- 任何區域性物件,區域性變數,區域性物件地址,區域性變數地址都不是常量表示式,都不能用作非型別模板形參的實參。全域性指標,全域性變數,全域性物件也不是一個常量表示式,不能用作非型別模板形參的實參
- 全域性變數的地址或引用,全域性物件的地址或引用,const型別變數是常量表示式,可以用作非型別模板形參的實參
- sizeof表示式的結果是一個常量表示式,也能用作非型別模板形參的實參
- 當模板的形參是整型時呼叫該函式的實參必須時整型,且在編譯期間是常量。比如int b,AA<int ,b> a1;這時編譯器就會報錯,因為b是一個變數,如果修改為const int b,AA<int ,b> a1;就不會出錯,因為此時b是一個常量
非型別模板形參的形參和實參間所允許的轉換
- 允許從陣列到指標,從函式到指標。
template<int *>
class A
{};
void Test()
{
int b[1];
A<b> a1;
}
2.const修飾符的轉換
template<const int*a>
class A {};
void Test()
{
int* b;
A<&b> a1;//從int* 到const int* 的轉換
}
3.提升轉換(short——int)
4.整值轉換(int ——unsigned int)
模板形參總結:
- 型別引數:可以給類别範本的型別形參提供預設值,但不能給函式模板的型別形參提供預設值。
- 非型別引數:函式模板和類别範本都可以為類别範本的非型別形參提供預設值
- 給類别範本的型別形參預設值的方式:
template<class T1,class T2=int> class AA{};
-
類别範本的型別引數提供預設值的方式與函式預設一樣,要從右向左,不能給T1提供預設值而不給T2。
-
在類别範本的外部定義類中的成員時template後的形參表應省略預設的形參型別
template <calss T1,class T2 = int> class A { public: void h(); }; viod A<T1,T2>::h() {}
模板的模板引數:
template<class T>
class Seqlist
{
private:
int _size;
int _capacity;
T* _data;
};
template<class T, template<class>calss Container = Seqlist>
calss Stack
{
public:
void Push(const T& x);
void pop();
const T& Top();
private:
Container<T> _con;
}
void Test()
{
Stack<int> s1;
Stack<int, Seqlist>s2;
}
3.模板的分離編譯:
解決方法:
- 在模板標頭檔案xxx.h裡面顯示例項化->模板類的定義後面新增template class SeqList<int>;
- 一般不推薦這種方法,一方面老編譯器可能不支援,另一方面例項化依賴呼叫者
- 將宣告和定義放在同一個檔案“xxx.hpp”裡面,新增使用這種方法
相關文章
- 為什麼C++編譯器不能支援對模板的分離式編譯 (轉)C++編譯
- Vue 模板編譯原理Vue編譯原理
- c++ 模板模板引數("Template Template Parameters")C++
- 前端面試-模板編譯前端面試編譯
- 模板函式編譯原理函式編譯原理
- 從模板中分離出引數無關的程式碼(轉)
- vue模板編譯(原理篇)Vue編譯
- c++11-17 模板核心知識(十二)—— 模板的模板引數 Template Template ParametersC++
- c++可變模板引數C++
- 數值型模板引數的應用
- C++11 可變引數模板C++
- [譯]編寫可以複用的 HTML 模板HTML
- vue原理:diff、模板編譯、渲染過程等Vue編譯
- Ant 編譯、打包 build.xml 指令碼模板編譯UIXML指令碼
- php編譯引數PHP編譯
- c++11-17 模板核心知識(五)—— 理解模板引數推導規則C++
- 模板 - 數論
- Vue3 模板編譯原理 (Vue 的編譯模組整體邏輯)Vue編譯原理
- 《Vue不看原始碼懂原理》系列——Vue模板編譯Vue原始碼編譯
- c++模板類的使用,編譯的問題C++編譯
- 檢視編譯引數編譯
- 編譯引數檢視編譯
- C++ 可變引數模板遞迴展開C++遞迴
- 長鏈剖分模板
- 模板 - 二分&三分
- PHP 編譯引數儲存PHP編譯
- PHP編譯安裝引數PHP編譯
- gcc最佳編譯引數(轉)GC編譯
- ZBlogPHP主題模板的編譯檔案不存在PHP編譯
- 2.diff差分【模板】
- 二維座標離散化模板
- 大質數分解模板
- 編譯引數-ObjC的說明編譯OBJ
- (譯)理解 T4 模板: 指令
- SQL Server 2005中的模板引數的利用方法SQLServer
- Gif開發筆記(一):gif介紹、編譯和工程模板筆記編譯
- Vue原始碼模板編譯階段----HTML解析器腦圖Vue原始碼編譯HTML
- C++模板”>>”編譯問題與詞法消歧設計C++編譯