未显式传入尺寸信息时,C++模板函数如何获取std::array行列大小?
为什么模板能自动推导二维std::array的行列尺寸?
先把你的代码格式化得更清晰一点:
template<size_t ROWS, size_t COLS> void f(const array<array<int, COLS>, ROWS>& arr) { for(size_t r=0; r<ROWS; r++) for(size_t c=0; c<COLS; c++) // 这里处理元素 } array<array<int, 2>, 3> arr {{{1,2},{3,4},{5,6}}}; f(arr);
这个问题问得特别到位!核心其实很简单:std::array的类型本身就携带了它的尺寸信息,编译器只是从实参的完整类型里把这些信息“读”出来而已。
先搞懂std::array的本质
std::array不是普通的C风格数组,它是一个模板类,简化后的定义大概是这样:
template <typename ElementType, size_t Size> struct array { // 内部成员和方法 };
你写array<int, 2>的时候,这个类型就已经明确告诉编译器:“我是一个能装2个int的数组”。而你的二维数组array<array<int, 2>, 3>,意思就是“我是一个能装3个array<int,2>的数组”——相当于类型里直接写了“3行2列”的信息。
模板参数推导的具体过程
当你调用f(arr)时,编译器会自动完成以下匹配:
- 函数模板的形参类型是
const array<array<int, COLS>, ROWS>&,这里有两个待确定的模板参数ROWS和COLS。 - 实参
arr的实际类型是array<array<int, 2>, 3>,这个类型里的两个尺寸是明明白白的:外层数组的大小是3,内层数组的大小是2。 - 编译器会把这两个类型做模式匹配:
- 外层
array的第二个模板参数(也就是行数)是3,刚好对应形参里的ROWS,所以ROWS被推导为3; - 内层
array的第二个模板参数(也就是列数)是2,对应形参里的COLS,所以COLS被推导为2。
- 外层
说白了,你不需要显式写f<3,2>(arr),因为变量arr的类型已经把尺寸信息“刻”在里面了,编译器只要对照着函数模板的形参类型,就能自动把这两个参数填进去。
额外提一句:C风格数组也能这么玩
其实如果是普通的C风格二维数组int arr[3][2],函数模板同样能推导出行列尺寸,原理是一样的——C风格数组的类型也携带了维度信息。只不过std::array作为模板类,这种推导逻辑更直观,也更符合现代C++的类型安全设计。
内容的提问来源于stack exchange,提问作者code
相关产品推荐
相关产品推荐

