将模板用作数组维度时模板如何工作?
How do templates work when using them as array dimensions?
我尝试使用模板作为数组维度值。当试图将错误的维度指定为模板参数时,我感到很困惑。例如代码:
#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
}
为什么最后一个案例编译失败,而 <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
你得到这个结果是因为 f(int a[X][Y])
是一个 谎言 .
数组不是 C++ 中的第一个 class 公民。您不能按值将数组作为函数参数传递。所以当你写这样的参数时,它被默默地调整为一个指针(仅限第一级)。因此 a
的类型实际上是 int (*)[Y]
.
因为 a
类型中没有 X
,所以任何 X
都可以。
如果您想强制执行 X
和 Y
,请尝试通过引用传递数组 :
void f(int (&a)[X][Y])
或使用std::array
.
我尝试使用模板作为数组维度值。当试图将错误的维度指定为模板参数时,我感到很困惑。例如代码:
#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
}
为什么最后一个案例编译失败,而 <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
你得到这个结果是因为 f(int a[X][Y])
是一个 谎言 .
数组不是 C++ 中的第一个 class 公民。您不能按值将数组作为函数参数传递。所以当你写这样的参数时,它被默默地调整为一个指针(仅限第一级)。因此 a
的类型实际上是 int (*)[Y]
.
因为 a
类型中没有 X
,所以任何 X
都可以。
如果您想强制执行 X
和 Y
,请尝试通过引用传递数组 :
void f(int (&a)[X][Y])
或使用std::array
.