当定义为模板参数时,编译器如何推断数组大小?

时间:2016-06-21 19:03:38

标签: c++ arrays templates reference template-deduction

我想知道在下面的代码中,编译器如何从arrsize函数参数中推导出T (&arr)[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. 如果我正常传递数组,为什么编译器不能这样做? (通常我的意思是不使用参考符号)

2 个答案:

答案 0 :(得分:2)

T arr[arrsize]作为正式参数衰减到T* arr,其中arrsize被完全忽略(实际上是该参数的数组性质)。

答案 1 :(得分: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,因此无法推断出。{/ li>