当定义为模板参数时,编译器如何推断数组大小?
How does the compiler deduce array size when defined as a template parameter?
我想知道在下面的代码中,编译器如何从 T (&arr)[arrsize]
函数参数中推导出 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]);
}
所以我的问题是:
当我向函数传递对数组的引用时,编译器如何自动计算出 arrsize
参数的值? (什么机制?)
如果我正常传递数组,为什么编译器不能做同样的事情? (通常我的意思是不使用参考符号)
T arr[arrsize]
作为正式参数衰减为 T* arr
,其中 arrsize
被完全忽略(实际上是该参数的数组性质)。
- 它可以推断出大小,因为大小在调用上下文中的编译时是已知的。如果你有
int a[4]
,而你写 bubblesort(a)
,那么编译器会使用 a
的类型是 int[4]
的事实来推断 arrsize
为 4。如果当 p
的类型为 int*
时,您尝试执行 bubblesort(p)
,推导将失败并导致编译错误。
- 如果你写
T arr[arrsize]
作为参数而不是T (&arr)[arrsize]
,那么编译器会自动将声明重写为T* arr
。由于arrsize
不再出现在签名中,因此无法推导出。
我想知道在下面的代码中,编译器如何从 T (&arr)[arrsize]
函数参数中推导出 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]);
}
所以我的问题是:
当我向函数传递对数组的引用时,编译器如何自动计算出
arrsize
参数的值? (什么机制?)如果我正常传递数组,为什么编译器不能做同样的事情? (通常我的意思是不使用参考符号)
T arr[arrsize]
作为正式参数衰减为 T* arr
,其中 arrsize
被完全忽略(实际上是该参数的数组性质)。
- 它可以推断出大小,因为大小在调用上下文中的编译时是已知的。如果你有
int a[4]
,而你写bubblesort(a)
,那么编译器会使用a
的类型是int[4]
的事实来推断arrsize
为 4。如果当p
的类型为int*
时,您尝试执行bubblesort(p)
,推导将失败并导致编译错误。 - 如果你写
T arr[arrsize]
作为参数而不是T (&arr)[arrsize]
,那么编译器会自动将声明重写为T* arr
。由于arrsize
不再出现在签名中,因此无法推导出。