Search code examples
c++templatestemplate-argument-deduction

How does this function template deduce the size of an array?


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)?


Solution

  • N does not get "initialized" to anything. It is not a variable. It is not an object. N is a compile-time constant. N only exists during compilation. The value of N as well as the actual T is determined by the process called template argument deduction. Both T and N are 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 that T == int and N == 6, generates a separate function for that and calls it. Let's name it cal_size_int_6

    void cal_size_int_6(int (&a)[6]) 
    { 
      std::cout << "size of array is: " << 6 << std::endl; 
    } 
    

    Note that there's no T and no N in 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 that T == int and N == 1, generates a separate function for that as well and calls it. Let's name it cal_size_int_1

    void cal_size_int_1(int (&a)[1]) 
    { 
      std::cout << "size of array is: " << 1 << std::endl; 
    } 
    

    Same thing here.

    Your main essentially translates into

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

    In other words, your cal_size template gives birth to two different functions (so called specializations of the original template), each with different values of N (and T) hardcoded into the body. That's how templates work in C++.