我們知道,用模板的時候可以為他提供兩種型別的模板形參:一種是型別模板形參,一種是非型別模板形參。例如如下宣告:
class t>
void foo(t t);
//用的型別模板形參
class t,
int n>
void foo(t t);
//用了型別模板形參,同時還用到了非型別模板形參int
兩者的區別是:對應型別模板形參,編譯器會根據實參(對應模板函式)或者使用者指定型別來例項化對應的模板函式或型別。而非型別模板形參主要是用來在模板函式呼叫時指定該形參的值。
非型別模板形參最常用的是用來自動獲取陣列的維數。比如,我們給某個函式傳遞乙個陣列,並在函式內部列印這個陣列的值,如果沒有模板,我們的做法就可能是如下這樣:
void print(
int r,
int n) ;
print(ss); //或者print<
int>(ss);
return 0; }
編譯器會抱怨說:「void print(t [n])」: 未能從「int [9]」為「int [n]」推導 模板 引數」。也就是我們還是得指定n:print(ss)才行。如果是這樣,那豈不還不如將維數放到函式的引數裡面了。是不是?
其實,這完全不能怪編譯器或者模板,因為只要這樣寫就完全可以了:
template<
class t,
int n>
void print(t (&r)[n]) ;
(ss);
return 0;
執行結果如下:
361,2,3,4,5,6,7,8,9,
41,2,3,4,5,6,7,8,9,
很明顯可以看出,傳引用的方式他知道是乙個陣列,所以sizeof是按陣列的方式計算的4*9=36.而第二種方式儘管我告訴他維數了,並且列印出結果了,但是絲毫沒有改變編譯器將print1的引數t r[n]視為乙個指標的事實,所以sizeof的值為4.
好了,總結一下就是:
如果希望用非型別模板形參的方式取陣列的維數時,請記住用陣列引用的方式作為形參!
模板非型別形參
今天看c primer看到16.4.2節內容,非型別形參的模板實參 自己突發奇想非型別形參是否支援型別轉換,於是鍵入double型資料,編譯器提示模板形參錯誤 vs2010,error 表示式必須包含整數或列舉型別 可見不僅不支援型別轉換,更不能允許形參為整型與列舉型別之外的型別。不見黃河不死心,於...
模板非型別形參
今天看c primer看到16.4.2節內容,非型別形參的模板實參 自己突發奇想非型別形參是否支援型別轉換,於是鍵入double型資料,編譯器提示模板形參錯誤 vs2010,error 表示式必須包含整數或列舉型別 可見不僅不支援型別轉換,更不能允許形參為整型與列舉型別之外的型別。不見黃河不死心,於...
非型別形參的模板實參
模板形參不必都是型別。在呼叫函式時非型別形參將用值代替,值的型別在模板列表中指定。例如,下面的函式模板宣告了array init是乙個含有乙個型別模板形參和乙個非型別模板形參的函式模板。函式本身接受乙個形參,該形參是陣列的引用。模板非型別形參是模板定義內部的常量值,在需要常量表示式的時候,可使用非型...