c++之數組形參


1.問題,最近看項目log模塊,_log模板函數中的一個參數竟然看蒙x了。函數原形是這樣:

template<size_t size>
void _Log(char (&strDest)[size], const char *scetion, const char *key, const char *msg, va_list &parm);

對!就是 char (&strDest)[size]沒有看懂。這個傳進來的是個字符串數組。

2.翻開c++聖經<c++primer>,找到答案。設計模板類型形參中的 非類型形參和數組引用類型形參。

    首先,數組作為形參,有引用和非引用兩種形式。一般我們使用非引用形式,也就是將形參定義為數組元素類型的指針,一共有三個等價形式:

  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<size_t size>

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函數中的第一個形參已經弄清--數組的應用型形參。同時利用模板的非類型形參,除去了數組長度的限制。

  水平有限,歡迎指正錯誤。

 

  

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM