Home > Net >  Why C template array length deduction need to be like "f(T (&a)[N]"?
Why C template array length deduction need to be like "f(T (&a)[N]"?

Time:06-28

Use C template to know the length of C-style array, we need this:

#include<stdio.h>
template<class T,size_t N>
size_t length(T (&a)[N]){ return N; }
int main() {
    int fd[2];
    printf("%lld\n", length(fd));;
    return 0;
}

It works, prints 2. My question is about the syntax.

In the declaration of length, why the parameter should be like (&a)[N], and a[N] doesn't work?

If I change to

template<class T,size_t N>
size_t length(T a[N]){ return N; }

gcc will say:

template argument deduction/substitution failed:
couldn't deduce template parameter 'N'

Why need an extra & and a pair of braces around array identifier here, what's the template rule / syntax rule behind this?

Appreciate detailed explanations.

CodePudding user response:

In this function declaration

template<class T,size_t N>
size_t length(T a[N]){ return N; }

the compiler adjusts the parameter having the array type to pointer to the array element type.

That is this declaration actually is equivalent to

template<class T,size_t N>
size_t length(T *a){ return N; }

On the other hand, the array used as an argument expression in this call

length(fd)

is implicitly converted to a pointer to its first element.

So the compiler cannot deduce the value of the template non-type parameter N.

When the parameter is declared as a reference then such an adjustment and implicit conversion as described above do not occur. The reference serves as an alias for the array.

Pay attention to that to output objects of the unsigned integer type size_t with the C function printf you need to use the conversion specifier zu instead of lld.

  • Related