栈分配数组函数模板调用报错:实参列表不匹配
问题描述
我编写了一个用于传递栈分配数组的函数模板,代码如下:
struct Pos { int row; int col; Pos(int r, int c) { row = r; col = c; } Pos() { row = 0; col = 0; } }; template <int R, int C> void traverse(int (&matrix)[R][C], bool (&visited)[R][C], Pos& target) { // 函数内部代码 };
在main函数中尝试以下方式调用该函数:
int matrix[rowSize][colSize]; bool visited[rowSize][colSize]; Pos target; target.row = 0; target.col = 0; traverse(matrix, visited, target);
使用g++编译时出现错误:
no instance of function template "traverse" matches the argument list.
我曾尝试过traverse(&matrix, &visited, target)和traverse(*matrix, *visited, target)两种调用方式,明知无效但仍尝试了。请问有什么修正建议或解决方案?
解决方案
问题核心是变长数组(VLA)与模板编译期参数不兼容:
C++标准并未定义变长数组(即rowSize/colSize为运行时确定的非const整数时声明的数组),这是GCC的扩展特性。而你的模板参数R、C要求是编译期常量,模板实例化必须在编译阶段确定这两个值,但变长数组的尺寸是运行时才确定的,编译器无法将运行时尺寸推导为编译期模板参数,导致匹配失败。
根据数组尺寸的确定时机,有两种解决方向:
1. 数组尺寸可在编译期确定
如果rowSize和colSize能提前确定为编译期常量,将其改为constexpr或直接使用字面量:
constexpr int rowSize = 5; constexpr int colSize = 5; int matrix[rowSize][colSize]; bool visited[rowSize][colSize]; // 此时编译器可自动推导模板参数R=5、C=5,调用正常 traverse(matrix, visited, target);
2. 数组尺寸必须在运行时确定
若数组大小只能在运行时决定,可采用以下两种替代方案:
方案A:传递指针+尺寸参数
修改函数为普通函数,手动传入行列数,通过指针计算访问元素:
void traverse(int* matrix, bool* visited, int rows, int cols, Pos& target) { // 访问matrix[i][j]时,用 matrix[i * cols + j] 替代 } // 调用方式 traverse(&matrix[0][0], &visited[0][0], rowSize, colSize, target);
方案B:使用标准容器替代变长数组
用std::vector模拟二维数组,完全符合C++标准,代码更易维护:
#include <vector> void traverse(std::vector<std::vector<int>>& matrix, std::vector<std::vector<bool>>& visited, Pos& target) { // 可直接用matrix[i][j]访问元素 } // 调用方式 std::vector<std::vector<int>> matrix(rowSize, std::vector<int>(colSize)); std::vector<std::vector<bool>> visited(rowSize, std::vector<bool>(colSize)); traverse(matrix, visited, target);
内容的提问来源于stack exchange,提问作者Hyun
相关产品推荐
相关产品推荐

