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
.