繁体   English   中英

为什么模板参数推导在 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])

但为什么? 当数组按值传递时,您能否解释一下为什么编译器无法预测第一个示例中的数组大小?

这个函数声明

void PrintArray(const int arr[n]) {

相当于

void PrintArray(const int *arr) {

由于编译器将具有数组类型的参数调整为指向数组元素类型的指针。

来自 C++ 14 标准(8.3.5 函数)

5 一个名称可以在一个范围内用于多个不同的功能; 这是函数重载(第 13 条)。 函数的所有声明在返回类型和参数类型列表中都应完全一致。 使用以下规则确定函数的类型。 每个参数的类型(包括函数参数包)由其自己的 decl-specifier-seq 和 declarator 确定。 在确定每个参数的类型后,任何类型为“T 的数组”或“返回 T 的函数”类型的参数分别调整为“指向 T 的指针”或“指向返回 T 的函数的指针”。 生成参数类型列表后,在形成函数类型时删除任何修改参数类型的顶级 cv 限定符。 转换后的参数类型的结果列表以及省略号或函数参数包的存在与否就是函数的参数类型列表。 [ 注意:此转换不影响参数的类型。 例如, int( )(const int p, decltype(p) ) 和 int( )(int, const int ) 是相同的类型。 — 尾注 ]

所以不可能推导出模板参数n。

像这样声明函数

void PrintArray(const int ( &arr )[n]) {

或者您可以通过显式指定模板参数来调用原始函数,例如

PrintArray<5>(arr);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM