Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between int a[5] and int (&a)[5] in template parameter deduction

This question is about functions that take arrays of statically known size.

Take for example the following minimal program:

#include <iostream>

template<size_t N>
void arrfun_a(int a[N])
{
    for(size_t i = 0; i < N; ++i)
        std::cout << a[i]++ << " ";
}

int main()
{
    int a[] = { 1, 2, 3, 4, 5 };
    arrfun_a<5>(a);
    std::cout << std::endl;
    arrfun_a<5>(a);

    return 0;
}

Which, when run, prints the expected result:

2 3 4 5 6
3 4 5 6 7

However, when I tried to have my compiler (VS 2010) deduce the 5, it could not deduce template argument for 'int [n]' from 'int [5]'.

A bit of research resulted in the updated arrfun_b where the template parameter deduction works:

template<size_t n>
void arrfun_b(int (&a)[n])
{
    for(size_t i = 0; i < n; ++i)
        std::cout << ++(a[i]) << std::endl;
}

The result of the program is the same, whether arrfun_a or arrfun_b is called.

So far, the only difference I have found is whether the template argument deduction works and if it is possible to call the function with an N that is not 5...

like image 929
gha.st Avatar asked May 08 '12 19:05

gha.st


2 Answers

The compiler silently changes the type of function argument int a[N] to int *a and thus loses the size of the array. int(&a)[5] is truly a reference to an array of size 5, and cannot be passed an array of any other size.

like image 139
Mark Ransom Avatar answered Oct 13 '22 23:10

Mark Ransom


I think its the difference between a reference and a pointer.

arrfun_a passes a pointer to int.

arrfun_b passes a reference to an array of ints.

like image 24
Julian Avatar answered Oct 13 '22 21:10

Julian