Imm*_*ant 2 c++ arrays templates pass-by-reference pass-by-value
使用C++模板来知道C风格数组的长度,我们需要这个:
#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;
}
Run Code Online (Sandbox Code Playgroud)
它可以工作,打印2。我的问题是关于语法的。
在 的声明中length,为什么参数应该像(&a)[N], 一样a[N]不起作用?
如果我改为
template<class T,size_t N>
size_t length(T a[N]){ return N; }
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会会说:
template argument deduction/substitution failed:
couldn't deduce template parameter 'N'
Run Code Online (Sandbox Code Playgroud)
为什么这里需要&在数组标识符周围添加一个额外的大括号,这背后的模板规则/语法规则是什么?
感谢详细的解释。
在这个函数声明中
template<class T,size_t N>
size_t length(T a[N]){ return N; }
Run Code Online (Sandbox Code Playgroud)
编译器将具有数组类型的参数调整为指向数组元素类型的指针。
也就是说这个声明实际上相当于
template<class T,size_t N>
size_t length(T *a){ return N; }
Run Code Online (Sandbox Code Playgroud)
另一方面,在此调用中用作参数表达式的数组
length(fd)
Run Code Online (Sandbox Code Playgroud)
隐式转换为指向其第一个元素的指针。
因此编译器无法推导出模板非类型参数 N 的值。
当参数被声明为引用时,则不会发生如上所述的调整和隐式转换。该引用用作数组的别名。
请注意,要使用size_tC 函数输出无符号整数类型的对象printf,您需要使用转换说明符zu而不是lld。