2012-05-08 59 views
8

這個問題是關於採用靜態已知大小的數組的函數。int a [5]和int(&a)[5]在模板參數推導中的區別

就拿以下最低程序:

#include <iostream> 

template<size_t N> 
void arrfun_a(int a[N]) 
{ 
    for(size_t i = 0; i < N; ++i) 
     std::cout << a[i]++ << " "; 
} 

int main() 
{ 
    int a[] = { 1, 2, 3, 4, 5 }; 
    arrfun_a<5>(a); 
    std::cout << std::endl; 
    arrfun_a<5>(a); 

    return 0; 
} 

其中,在運行時,打印預期的結果:

2 3 4 5 6 
3 4 5 6 7 

然而,當我試圖讓我的編譯器(VS 2010)推斷5,它could not deduce template argument for 'int [n]' from 'int [5]'

的研究有點導致更新arrfun_b其中模板參數推導原理:

template<size_t n> 
void arrfun_b(int (&a)[n]) 
{ 
    for(size_t i = 0; i < n; ++i) 
     std::cout << ++(a[i]) << std::endl; 
} 

該方案的結果是一樣的,arrfun_aarrfun_b是否被調用。

到目前爲止,我已經找到了唯一的區別就是模板參數推導是否正常工作,如果它是可調用的N不是5的功能...

+2

你確定,'兩個版本都允許顯式傳遞一個更小或更大的N'嗎?它不應該和[不](http://ideone.com/74FaV)。這是另一個_pro_使用參考版本 – Lol4t0

+0

謝謝你解決我的困惑!在測試過程中的某個地方,我一定已經搞砸了! –

+0

您必須不刪除非參考版本並創建了稱爲的重載。 – Lol4t0

回答

14

編譯器默默改變的類型函數參數int a[N]int *a,從而丟失數組的大小。 int(&a)[5]確實是對大小爲5的數組的引用,並且不能傳遞任何其他大小的數組。

+5

更多重要的是,'int a [5]'在參數列表中變爲'int * a',其中'int(&a)[5]'確實是一個**引用**到一個由5個int組成的數組 –

+1

@D。肖利,我暗示說,但沒有說清楚。謝謝。 –

+0

在這種情況下,對'arrfun_a'的調用會包含一個數組到指針的衰減,然後是隱式指針到數組的轉換,給我一個完全無用的編譯器消息? * great * –

1

我認爲它的參考和指針之間的區別。

arrfun_a將一個指針傳遞給int。

arrfun_b將引用傳遞給一個int數組。

相關問題