2013-11-23 87 views
2

下面的代碼對我來說工作正常。在C++中通過引用傳遞數組模板函數

#include <iostream> 
using namespace std; 

template<class T> 
T sum_array(T (&a)[10], int size) 
{ 
    T result=0; 
    for(int i=0; i<size; i++) 
    { 
     result = a[i] + result; 
    } 
    return result; 
} 

int main() 
{ 
    int a[10] = {0,1,2,3,4,5,6,7,8,9}; 
    cout<<sum_array(a, 10)<<endl; 
    double d[10] = {1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1,1.1}; 
    cout<<sum_array(d, 10)<<endl; 
    cin.get(); 
} 

但如果儘量讓我的功能更通用的如功能圖所示,它提供了錯誤說沒有函數模板實例中移除數組大小。

template<class T> 
T sum_array(T (&a)[], int size) 
{ 
    T result=0; 
    for(int i=0; i<size; i++) 
    { 
     result = a[i] + result; 
    } 
    return result; 
} 

在同一時間,如果我刪除參考如下所示,它只是工作正常。

template<class T> 
T sum_array(T a[], int size) 
{ 
    T result=0; 
    for(int i=0; i<size; i++) 
    { 
     result = a[i] + result; 
    } 
    return result; 
} 

我是比較新的模板可以請你解釋上述行爲。

+0

可能最好是使用'的std ::陣列'對於這種情況 –

回答

2

在函數參數中,[](沒有維度內部)只是指針的替代語法,因爲數組在傳遞給函數時衰減爲指針,除非它們通過引用傳遞。

這意味着您的工作概括模板(與T a[]一致)與T a*完全相同。如果你在運行時傳遞大小,一切都很好,你可以使用它(並且它可以用於沒有聲明爲數組的其他東西,比如返回值std::string::c_str())。

但是,如果要概括tempalte但仍保持它僅限於實際的數組,你可以這樣做:

template<class T, size_t N> 
T sum_array(T (&a)[N], int size) 
{ 
    T result=0; 
    for(int i=0; i<size; i++) 
    { 
     result = a[i] + result; 
    } 
    return result; 
} 

這樣,只有一個真正的數組可以傳遞的,但它的兩個類型T及其長度N將被推斷。根據您的使用情況,在這種情況下,您可能會刪除size參數。

+0

你可以把它改成 模板<類T,爲size_t N> Ťsum_array(T(&一)[N])。讀者可能不會讀你的最後一行。 – ashish

0

如果你想通過引用來綁定數組,你絕對需要知道數組的大小。但是,您可以使用來編譯器推導出大小。假設你的代碼中的邏輯是不平凡的,立即委託到獨立於數組大小的版本是一個好主意。這裏有一個例子:

template<typename T> 
T sum_array(T const* a, int size) 
{ 
    return std::accumulate(a, a + size, T()); 
} 

template <typename T, int Size> 
T sum_array(T const (&array)[Size]) { 
    return sum_array(array, Size); 
} 

當然,我忍不住也使用0​​從<numeric>:如果有這個算法,它是用一個好主意。

由於您想知道如何從數組中刪除引用:當使用T[]作爲函數參數的類型時,它相當於使用T*。即使你使用T[10]作爲函數參數的類型,編譯器也會將它讀作T*