2013-11-23 90 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*