1.問題,最近看專案log模組,_log模板函式中的乙個引數竟然看蒙x了。函式原形是這樣:
template
void _log(char (&strdest)[size], const char *scetion, const char *key, const char *msg, va_list &parm);
對!就是 char (&strdest)[size]沒有看懂。這個傳進來的是個字串陣列。
2.翻開c++聖經,找到答案。設計模板型別形參中的 非型別形參和陣列引用型別形參。
首先,陣列作為形參,有引用和非引用兩種形式。一般我們使用非引用形式,也就是將形參定義為陣列元素型別的指標,一共有三個等價形式:
1.void func(int *p);
2.void func(int p);
3.void func(int p[10]);
其中第三個顯示的表明 呼叫該函式時,所傳遞的陣列最多有10個元素。但是實際上編譯器會忽略為任何陣列指定的形參長度,換句話說,第三個函式宣告中的10,其實是被編譯器忽略的。
當我們呼叫上邊的函式時,傳遞陣列名時,陣列名會自動轉化為指向陣列第乙個元素的指標。也就是該指標所存放的是陣列第乙個元素的位址。 然後形參複製的是這個指標指向的位址。
然後,當陣列作為形參,採用引用的方式時,形式是這樣:
1.void func(int (&p)[10]);
當呼叫此函式時,必須傳遞的是 具有10個int型元素的陣列。類似這樣
int a[10] = {};
func(a);
如果這樣 int b[2] = {}; func(b); 是不正確的,因為b不是10個元素。當形參是引用型別時,理解引用的含義很重要。引用就是乙個變數的別名,但是終究是該變數自己。
同時,使用引用時,沒有複製的環節,大多時候會節省空間,提公升效率。
3.但是,我們可以看出,以上形式的陣列的引用型形參,是很不方便的。因為傳遞陣列時,存在型別和長度的雙重限制。
那麼有沒有一種方法,能夠解決上述問題呢? 既能用到引用的有點,同時又能避免長度帶來的限制?
答案就是採用 1. 中的模板函式以及使用非型別模板形參。
template
void func(int (&p)[size])
聖經中講到:模板非型別形參是模板定義內部的常量值,在需要常量表示式的時候,可使用非型別形參指定陣列的長度, 當呼叫 func是,編譯器會從陣列的實參計算非型別形參的值,也就是編譯器替我們
計算好了size的值,從而省去我們自己傳遞長度。這樣一來,就可以傳遞陣列元素相同的陣列了,不必擔心長度。從而避免了2中的缺點
這樣一來:
int a[10], b[2];
func(a);func(b)都可以正確呼叫,同時size的值為a和b的陣列長度。
另外一點需要說明,儘管用了模板的非型別形參,讓我們可以省去陣列長度的限制,但是實際上,編譯器會產生兩個func的例項 func<10>, func<2>.
如果此時宣告 int c[10]; func(c); 此時a和c將使用相同的例項。
這基於: 對於模板的非型別形參而言,求值結果形同的表示式將認為是等價的。
因此 a和c呼叫 func(int (&p)[10]), b呼叫 func(int (&p)[2]).
4.至此,_log函式中的第乙個形參已經弄清--陣列的應用型形參。同時利用模板的非型別形參,除去了陣列長度的限制。
水平有限,歡迎指正錯誤。
C 陣列形參
1.c primer 首先,陣列作為形參,有引用和非引用兩種形式。一般我們使用非引用形式,也就是將形參定義為陣列元素型別的指標,一共有三個等價形式 1.void func int p 2.void func int p 3.void func int p 10 template void log c...
C 陣列形參的傳遞
陣列有兩個特性 傳參的方法 當下有乙個陣列int j 2 我們自寫了乙個函式void findsomeone 要求將陣列引數傳進去。有以下兩種方式 在函式內部使用時,point 即可實現指標的移動 陣列大小 陣列是以指標的形式傳遞給函式的,所以函式並不知道陣列的確切尺寸,因此呼叫者應該為此提供一些資...
7 2 4陣列形參
1.編譯器不會檢查實參陣列的長度 2.通過引用傳遞陣列 void printvalues int arr 10 編譯器檢查實參的大小.3.main 處理命令列選項 code include using namespace std int main int argc,char argv else 4....