I am wondering how, in the following piece of code, the compiler deduces the arrsize
template argument from the T (&arr)[arrsize]
function argument. For example, when I pass a 4-element array to it, without mentioning the number 4 in my call to the function, it correctly determines the arrsize
argument to be 4. However, if I pass the array normally (not as a reference to array), that is, if I change T (&arr)[arrsize]
to T arr[arrsize]
, it requires me to explicitly provide the arrsize
argument in the template argument list.
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]);
}
So my question is:
How does the compiler figure out the value of the
arrsize
argument automatically when I pass to the function a reference to an array? (What is the mechanism?)Why can the compiler not do the same if I pass the array normally? (by normally I mean without using the reference symbol)
int a[4]
, and you writebubblesort(a)
, then the compiler uses the fact that the type ofa
isint[4]
to deducearrsize
as 4. If you try to dobubblesort(p)
whenp
has typeint*
, deduction will fail and a compile error will result.T arr[arrsize]
as the parameter instead ofT (&arr)[arrsize]
, then the compiler will automatically rewrite the declaration asT* arr
. Sincearrsize
no longer occurs in the signature, it can't be deduced.T arr[arrsize]
as a formal argument decays to justT* arr
, where thearrsize
is ignored completely (as indeed is the array nature of that argument).