提问人:sshd 提问时间:10/20/2021 更新时间:10/20/2021 访问量:71
为什么模板参数推导在 C++ 中不起作用?
Why template argument deduction doesn't work in C++?
问:
我在 C++ 中对模板参数推导有疑问。 我不知道为什么下面的示例不起作用。 示例:
#include <iostream>
template<size_t n>
void PrintArray(const int arr[n]) {
for (int i = 0; i < n; i++)
printf("%d\n", arr[i]);
}
int main() {
int arr[5] = {1, 2, 3, 3, 5};
PrintArray<>(arr);
return 0;
}
编译器打印此错误:
main.cpp: In function 'int main()':
main.cpp:12:21: error: no matching function for call to 'PrintArray(int [5])'
PrintArray<>(arr);
^
main.cpp:4:6: note: candidate: template<unsigned int n> void PrintArray(const int*)
void PrintArray(const int arr[n]) {
^~~~~~~~~~
main.cpp:4:6: note: template argument deduction/substitution failed:
main.cpp:12:21: note: couldn't deduce template parameter 'n'
PrintArray<>(arr);
我发现如果我通过引用传递参数,代码就会起作用,因此函数签名变成这样:
void PrintArray(const int (&arr)[n])
但是为什么?您能否解释一下为什么当数组按值传递时,编译器无法预测第一个样本中的数组大小?
答:
3赞
Vlad from Moscow
10/20/2021
#1
此函数声明
void PrintArray(const int arr[n]) {
相当于
void PrintArray(const int *arr) {
由于由编译器调整具有数组类型的参数,以指针指向数组元素类型。
来自 C++ 14 标准(8.3.5 函数)
5 一个名称可以用于 单一范围;这是函数重载(第 13 条)。都 函数的声明应在两个报表中完全一致 type 和 parametertype-list。确定函数的类型 使用以下规则。每个参数的类型(包括 function parameter packs) 由其自身确定 decl-specifier-seq 和声明器。确定类型后 每个参数,类型为“T 数组”或“函数”的任何参数 返回 T“被调整为”指向 T 的指针“或”指向函数的指针” 返回 T”。生成参数列表后 类型,任何修改参数类型的顶级 cv 限定符都是 形成函数类型时删除。生成的 转换后的参数类型以及是否存在 省略号或函数参数包是函数的 parameter-type-list。[ 注意:此转换不会影响 参数的类型。例如,int()(const int p, decltype(p)) 和 int()(int, const int) 是相同的类型。— 完 注 ]
所以无法推导出模板参数 n。
声明函数如下
void PrintArray(const int ( &arr )[n]) {
或者,您可以通过显式指定模板参数来调用原始函数,例如
PrintArray<5>(arr);
上一个:C 传递参考误解
评论