将模板用作数组维度时,模板如何工作?

spe*_*tor 3 c++ templates compiler-errors compilation

我尝试使用 tempaltes 作为数组维度值。当我试图将错误的维度指定为临时参数时,我感到很困惑。例如代码:

#include <iostream>

using namespace std;

template <int X, int Y>
void f(int a[X][Y]) {
    for (int i = 0; i < X; ++i) {
        for (int j = 0; j < Y; ++j) {
            cout << a[i][j] << " ";
        }
        cout << '\n';
    }
}

int main() {
    int a[2][2] = {{1, 2}, {3, 4}};
    f<2, 2>(a); // compilation succeeded
    f<10, 2>(a); // compilation succeeded
    f<2, 10>(a); // compilation FAILED
}
Run Code Online (Sandbox Code Playgroud)

为什么在最后一种情况下编译失败,但在 <10, 2> 情况下却没有?

error: no matching function for call to 'f'
note: candidate function template not viable: no known conversion from 'int [2][2]' to 'int (*)[10]' for 1st argument
Run Code Online (Sandbox Code Playgroud)

n. *_* m. 6

你得到这个结果是因为f(int a[X][Y])谎言

数组不是 C++ 中的一等公民。您不能按值将数组作为函数参数传递。因此,当您编写此类参数时,它会被静默调整为指针(仅限第一级)。因此类型a是真的int (*)[Y]

Since there is no X in the type of a, absolutely any X will work.

If you want to enforce both X and Y, try passing the array by reference:

void f(int (&a)[X][Y])
Run Code Online (Sandbox Code Playgroud)

or use std::array.