有三種型別的模板形參:型別形參,非型別形參和模板形參。型別形參由關見字class或typename後接說明符構成,如
templatevoid h(t a){};
其中t就是乙個型別形參,型別形參的名字由使用者自已確定。模板形參表示的是乙個未知的型別。模板型別形參可作為型別說明符用在模板中的任何地方,與內建型別說明符或類型別說明符的使用方式完全相同,即可以用於指定返回型別,變數宣告等。
比如:templatevoid h(t a, t b){}
,語句呼叫h(2, 3.2)將出錯,因為該語句給同一模板形參t指定了兩種型別,第乙個實參2把模板形參t指定為int,而第二個實參3.2把模板形參指定為double,兩種型別的形參不一致,會出錯。(針對函式模板)
注意:上面的結論針對函式模板是正確的,但是不適用於類模板。下面將對類模板的情況進行補充。
當我們宣告類物件為:aa
,比如templatet g(t a, t b){}
,語句呼叫a.g(2, 3.2)在編譯時不會出錯,但會有警告,因為在宣告類物件的時候已經將t轉換為int型別,而第二個實參3.2把模板形參指定為double,在執行時,會對3.2進行強制型別轉換為3。當我們宣告類的物件為:aa
,此時就不會有上述的警告,因為從int到double是自動型別轉換。
驗證**如下:
其中int a就是非型別的模板形參。
#ifndef template_demo_hxx
#define template_demo_hxx
template
class a;
#endif
#include
#include "templatedemo.h"
template
a::a(){}
template
t a::g(t a,t b)
void main();
(2)非型別形參在模板定義的內部是常量值,也就是說非型別形參在模板的內部是常量。
(3)模板的非型別形參只能是整型,指標和引用
像
double,string, string **
這樣的型別是不允許的。但是double &,double *
,物件的引用或指標是正確的。(4)呼叫非型別模板形參的實參必須是乙個常量表示式,即他必須能在編譯時計算出結果。
(5)注意:任何區域性物件,區域性變數,區域性物件的位址,區域性變數的位址都不是乙個常量表示式,都不能用作非型別模板形參的實參。全域性指標型別,全域性變數,全域性物件也不是乙個常量表示式,不能用作非型別模板形參的實參。
(6) 全域性變數的位址或引用,全域性物件的位址或引用const型別變數是常量表示式,可以用作非型別模板形參的實參。
(7)sizeof表示式的結果是乙個常量表示式,也能用作非型別模板形參的實參。
(8)當模板的形參是整型時呼叫該模板時的實參必須是整型的,且在編譯期間是常量,比如
template class a{};
如果有int b,這時am;
將出錯,因為b不是常量,如果const int b
,這時am;
就是正確的,因為這時b是常量。(9)非型別形參一般不應用於函式模板中,比如有函式模板
templatevoid h(t b){}
,若使用h(2)呼叫會出現無法為非型別形參a推演出引數的錯誤,對這種模板函式可以用顯示模板實參來解決,如用h(2)
這樣就把非型別形參a設定為整數3。顯示模板實參在後面介紹。(10) 非型別模板形參的形參和實參間所允許的轉換
a、允許從陣列到指標,從函式到指標的轉換。如:
template class a{}; int b[1]; am;
即陣列到指標的轉換b、const修飾符的轉換。如:
templateclass a{}; int b; a<&b> m;
即從int *到const int *
的轉換。c、提公升轉換。如:
templateclass a{}; const short b=2; am;
即從short到int 的提公升轉換d、整值轉換。如:
templateclass a{}; a<3> m;
即從int 到unsigned int的轉換。e、常規轉換。
例項:
//由使用者自己親自指定棧的大小,並實現棧的相關操作
#ifndef template_demo_hxx
#define template_demo_hxx
template
class stack
bool full() const
};template
stack::stack():numelems(0)
template
void stack::push(t const& elem)
elems[numelems] = elem; // 附加元素
++numelems; // 增加元素的個數
}template
void stack::pop()
--numelems; // 減少元素的個數
}template
t stack::top()const
return elems[numelems-1]; // 返回最後乙個元素
}#endif
#include
#include
#include
#include
#include "templatedemo.h"
int main()
catch (std::exception const& ex)
}
[1] C 之模板元程式設計
關於模板原程式設計知識強烈推薦 非常好!首先複述一下模板元程式設計,以下標紅或者加粗的地方是模板元程式設計的精髓 從程式設計范型 programming paradigm 上來說,c 模板是 函式式程式設計 functional programming 它的主要特點是 函式呼叫不產生任何 沒有可變的...
模板元程式設計 二
c 模板元程式設計是讓編譯器提前完成一些執行期的工作,這樣提高了程式的執行期速度。由編譯器完成,那些只能在編譯器做工作,可是在編譯器能使用的東西很少。模板機制是c 除了繼承之外的 重用的一項關鍵的機制,它在編譯器完成模板的例項化的特性滿足了能在編譯期做工作的基本條件。模板的特化和遞迴是元程式設計中的...
C 之 模板元程式設計(一)
利用模板特化機制實現編譯期條件選擇結構,利用遞迴模板實現編譯期迴圈結構,模板元程式則由編譯器在編譯期解釋執行。模板是c 支援引數化多型的工具,使用模板可以使使用者為類或者函式宣告一種一般模式,使得類中的某些資料成員或者成員函式的引數 返回值取得任意型別。模板是一種對型別進行引數化的工具 通常有兩種形...