2016-06-21 78 views
0

我想知道如何在下面的代碼片段中編譯器從T (&arr)[arrsize]函數參數中推導出arrsize模板參數。例如,當我將一個4元素的數組傳遞給它時,我沒有提到函數中的數字4,它正確地確定了arrsize參數爲4.但是,如果我正常傳遞數組(不作爲參考)數組),也就是說,如果我將T (&arr)[arrsize]更改爲T arr[arrsize],則需要我在模板參數列表中明確提供arrsize參數。定義爲模板參數時,編譯器如何推導出數組大小?

template <class T, int arrsize> void bubblesort(T (&arr)[arrsize], int order=1) 
{ 
    if (order==0) return; 
    bool ascending = (order>0); 
    int i,j; 
    for (i=arrsize; i>0; i--) 
     for (j=0; j<i-1; j++) 
      if (ascending?(arr[j]>arr[j+1]):(arr[j]<arr[j+1])) swap(arr[j],arr[j+1]); 
} 

所以我的問題是:

  1. 編譯器如何弄不清arrsize參數值開機時自動傳遞給函數的數組的引用? (什麼是機制?)

  2. 爲什麼編譯器不能做同樣的事情,如果我正常傳遞數組? (由通常我的意思是不使用參考符號)

+0

'型ARR [arrsize]'來自C: -/ – Jarod42

回答

2
  1. 它可以推斷出大小,因爲大小在調用上下文中的編譯時間是已知的。如果你有int a[4],和你寫bubblesort(a),那麼編譯器使用的事實,a類型爲int[4]推斷arrsize爲4.如果你嘗試做bubblesort(p)p已鍵入int*,扣將失敗,並會導致編譯錯誤。
  2. 如果您編寫T arr[arrsize]作爲參數而不是T (&arr)[arrsize],那麼編譯器會自動將該聲明重寫爲T* arr。由於簽名中不再出現arrsize,因此無法推斷。
+1

和2是因爲C. – juanchopanza

+0

準確地說,是因爲老C.我覺得C11現在有VLA的類似的機制,不過這無關緊要到C++ 11。這兩種語言在過去的20年中有所分歧。 – MSalters

2

T arr[arrsize]作爲正式參數衰減到剛剛T* arr,其中arrsize完全被忽略(因爲實際上是一個參數的數組性質)。

相關問題