'How does this template magic determine array parameter size?

In the following code

#include<iostream>

 template<typename T,size_t N> 
 void cal_size(T (&a)[N])
 { 
     std::cout<<"size of array is: "<<N<<std::endl;
 }

 int main()
 {
     int a[]={1,2,3,4,5,6};
     int b[]={1};

     cal_size(a);
     cal_size(b);
 }

As expected the size of both the arrays gets printed. But how does N automatically gets initialized to the correct value of the array-size (arrays are being passed by reference)? How is the above code working?



Solution 1:[1]

It works because the type of a is "array of length 6 of int" and the type of b is "array of length 1 of int". The compiler knows this, so it can call the correct function. In particular, the first call calls the template instance cal_size<6>() and the second call calls cal_size<1>(), since those are the only template instantiations which match their respective arguments.

If you attempted to call an explicit template instance, it would only work if you got the size right, otherwise the arguments wouldn't match. Consider the following:

cal_size(a);    // ok, compiler figures out implicitly that N=6
cal_size<int, 6>(a); // also ok, same result as above
cal_size<int, 5>(a); // ERROR: a is not of type "array of length 5 of int"

Solution 2:[2]

when you declare int a[] = {1,2,3} it is the same as (or will be rewritten as) int a[3] = {1,2,3} since the templated function is receiving argument in form of T a[N], then N will have value of 3.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adam Rosenfield
Solution 2 i_am_jorf