1. 程式人生 > >C++引用形參+模板---解決陣列指標退化為指標

C++引用形參+模板---解決陣列指標退化為指標

C/C++中如果一個函式接受一個數組作為引數,那麼陣列將會被退化為指標,如果定義如下程式碼:

//陣列arr的大小未知。
int arrsize(int arr*) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1
}

在上面那段程式碼中不僅得到的陣列大小是不正確的,還會出現讓呼叫則不明白是傳遞int變數的地址,還是傳遞一個指標(陣列),為了解決第二個歧義現象,我們可以定義如下:

//陣列arr的大小依舊未知。
int arrsize(int arr[]) {
  cout
<< "element num : " << sizeof(arr) / sizeof(arr[0]) << endl; //1 }

即使我們按上面那種定義,但陣列的的大小我們依舊不知道,但現在編譯器還會提示類似如下警告:

 warning: ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int*’ [-Wsizeof-array-argument]

為了更好的解決上面的問題我們可以考慮使用一個引用形參,可以有如下程式碼:

//陣列arr的大小必須是12,否則會報錯。
int
arrsize_const_size(int (&arr)[12]) { cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12 }

即使我們使用引用形參解決了,在函式內部我們無法正確獲取陣列大小的問題,但更復雜的問題出現了,我們只能接受固定數量的大小的陣列,解決這個問題,我們可以通過一種很常規的手法定義函式如下:

 //指定一個數組大小n
int arrsize_n(int arr[], int n) {

}

上面雖然解決了,但我們多傳遞了一個引數,呼叫程式碼看起來沒有前兩個更加簡潔了,雖然問題被很好的解決了,為了更好的解決這個問題我們可以把推斷陣列大小的事交個編譯器,使用非型別模板引數。

template<int n>
int arrsize_template_size(int (&arr)[n]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  cout << "n : " << n << endl;//12
  for (int i = 0; i < n; i++) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
  }
  return 0;
}

下面給出完整的測試程式碼:

#include <iostream>

using namespace std;


//陣列arr的大小未知。
int arrsize(int arr[]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//1
  return 0;
}
//陣列arr的大小必須是12,否則會報錯。
int arrsize_const_size(int (&arr)[12]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  return 0;
}

//指定一個數組大小n
int arrsize_n(int arr[], int n) {
  return 0;
}

template<int n>
int arrsize_template_size(int (&arr)[n]) {
  cout << "element num : " << sizeof(arr) / sizeof(arr[0]) << endl;//12
  cout << "n : " << n << endl;//12
  for (int i = 0; i < n; i++) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
  }
  return 0;
}

int main() {

  int arr[12] = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
  };
  int arr1[16] = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    9, 10, 11, 12,
    13, 14, 15, 16,
  };

  arrsize(arr);
  arrsize_const_size(arr);
  cout << "-------------------------------------" << endl;
  arrsize_template_size(arr);
  cout << "-------------------------------------" << endl;
  arrsize_template_size(arr1);
  cout << "-------------------------------------" << endl;
  return 0;
}