2012-05-08 62 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数组。

相关问题