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. How does N automatically get initialized to the correct value of the array-size (arrays are being passed by reference)?
Ndoes not get “initialized” to anything. It is not a variable. It is not an object.Nis a compile-time constant.Nonly exists during compilation. The value ofNas well as the actualTis determined by the process called template argument deduction. BothTandNare deduced from the actual type of the argument you pass to your template function.In the first call the argument type is
int[6], so the compiler deduces thatT == intandN == 6, generates a separate function for that and calls it. Let’s name itcal_size_int_6Note that there’s no
Tand noNin this function anymore. Both were replaced by their actual deduced values at compile time.In the first call the argument type is
int[1], so the compiler deduces thatT == intandN == 1, generates a separate function for that as well and calls it. Let’s name itcal_size_int_1Same thing here.
Your
mainessentially translates intoIn other words, your
cal_sizetemplate gives birth to two different functions (so called specializations of the original template), each with different values ofN(andT) hardcoded into the body. That’s how templates work in C++.