You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::array与模板实现行列式计算时遇参数不匹配错误

问题:模板参数推导失败导致无法调用矩阵相关函数

我尝试编写一个计算N阶矩阵行列式的程序,借此首次学习std::array和模板,基于余子式与子式方法完成了如下实现:

#include <array>
#include <iostream>

template <int N>
using Matrix = std::array<std::array<double, N>, N>;

template <int N>
Matrix<N - 1> subMatrix(Matrix<N> matrix, size_t focusRow, size_t focusColumn) {
    Matrix<N - 1> returnMatrix;

    int subMatrixRow = 0, subMatrixColumn = 0;
    static const int matrixSize = matrix.size();

    for (size_t matrixRow = 0; matrixRow < matrixSize; matrixRow++) {
        for (size_t matrixColumn = 0; matrixColumn < matrixSize; matrixColumn++) {
            if (matrixRow != focusRow && matrixColumn != focusColumn) {
                returnMatrix[subMatrixRow][subMatrixColumn++] = matrix[matrixRow][matrixColumn];

                if (subMatrixColumn == matrixSize - 1) {
                    subMatrixColumn = 0;
                    subMatrixRow++;
                }
            }
        }
    }

    return returnMatrix;
}

template <int N>
double getDeterminant(Matrix<N> matrix) {
    static const int matrixSize = matrix.size();
    double determinant = 0;

    if (matrixSize == 1) {
        determinant = matrix[0][0];
    }

    else if (matrixSize == 2) {
        determinant = (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
    }

    else if (matrixSize > 0) {
        int sign = 1;

        for (size_t dimension = 0; dimension < N; dimension++) {
            determinant += sign * matrix[0][dimension] * getDeterminant(subMatrix(matrix, 0, dimension));
            sign = -sign;
        }
    }

    else {
        throw std::invalid_argument("expected square matrix");
    }

    return determinant;
}

int main(int argc, char const* argv[]) {
    static const int length = 3;

    Matrix<length> matrix = {{{1, 2, 3},
                              {4, 5, 6},
                              {7, 8, 9}}};

    printf("determinant = %.2f\n", getDeterminant(matrix));
}

执行make编译时出现如下错误:

vscode ➜ /workspaces/c-cpp-mirror/11032023-arrays $ make determinant
g++     determinant.cpp   -o determinant
determinant.cpp: In function ‘int main(int, const char**)’:
determinant.cpp:68:57: error: no matching function for call to ‘getDeterminant(Matrix<3>&)’
   68 |     printf("determinant = %.2f\n", getDeterminant(matrix));
      |                                                         ^
determinant.cpp:31:8: note: candidate: ‘template<int N> double getDeterminant(Matrix<N>)’
   31 | double getDeterminant(Matrix<N> matrix) {
      |        ^~~~~~~~~~~~~~
determinant.cpp:31:8: note:   template argument deduction/substitution failed:
determinant.cpp:68:57: note:   mismatched types ‘int’ and ‘long unsigned int’
   68 |     printf("determinant = %.2f\n", getDeterminant(matrix));
      |                                                         ^
make: *** [<builtin>: determinant] Error 1

以下是能复现该问题的简化程序:

#include <array>
#include <iostream>

template <int N>
using Matrix = std::array<std::array<double, N>, N>;

template <int N>
void printMatrix(Matrix<N> matrix) {}

int main(int argc, char const* argv[]) {
    static const int length = 4;

    Matrix<length> matrix = {{{7, -2, 2, 1},
                              {3, 1, -5, 2},
                              {2, 2, -5, 3},
                              {3, 2, 5, 1}}};

    printMatrix(matrix);
}

解决方法

问题根源

模板参数推导时,std::array::size()返回的是无符号整数类型(size_t),但代码中模板参数N被定义为signed int类型,类型不匹配导致推导失败。

方案1:显式指定模板参数

调用函数时手动指定模板参数,跳过自动推导:

// 原main函数中的调用修改为
printf("determinant = %.2f\n", getDeterminant<length>(matrix));

// 简化程序中的调用修改为
printMatrix<length>(matrix);

方案2:统一模板参数类型为无符号整数

将模板参数的int N改为std::size_t N(需包含<cstddef>头文件),与std::array的尺寸类型保持一致:

#include <array>
#include <iostream>
#include <cstddef> // 新增头文件

template <std::size_t N>
using Matrix = std::array<std::array<double, N>, N>;

template <std::size_t N>
Matrix<N - 1> subMatrix(Matrix<N> matrix, size_t focusRow, size_t focusColumn) {
    Matrix<N - 1> returnMatrix;

    int subMatrixRow = 0, subMatrixColumn = 0;
    constexpr std::size_t matrixSize = N; // 直接用模板参数,无需调用size()

    for (size_t matrixRow = 0; matrixRow < matrixSize; matrixRow++) {
        for (size_t matrixColumn = 0; matrixColumn < matrixSize; matrixColumn++) {
            if (matrixRow != focusRow && matrixColumn != focusColumn) {
                returnMatrix[subMatrixRow][subMatrixColumn++] = matrix[matrixRow][matrixColumn];

                if (subMatrixColumn == matrixSize - 1) {
                    subMatrixColumn = 0;
                    subMatrixRow++;
                }
            }
        }
    }

    return returnMatrix;
}

template <std::size_t N>
double getDeterminant(Matrix<N> matrix) {
    constexpr std::size_t matrixSize = N;
    double determinant = 0;

    if (matrixSize == 1) {
        determinant = matrix[0][0];
    }

    else if (matrixSize == 2) {
        determinant = (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
    }

    else if (matrixSize > 0) {
        int sign = 1;

        for (size_t dimension = 0; dimension < N; dimension++) {
            determinant += sign * matrix[0][dimension] * getDeterminant(subMatrix(matrix, 0, dimension));
            sign = -sign;
        }
    }

    else {
        throw std::invalid_argument("expected square matrix");
    }

    return determinant;
}

int main(int argc, char const* argv[]) {
    static const std::size_t length = 3; // 同步修改类型

    Matrix<length> matrix = {{{1, 2, 3},
                              {4, 5, 6},
                              {7, 8, 9}}};

    printf("determinant = %.2f\n", getDeterminant(matrix));
}

同时,代码中static const int matrixSize = matrix.size();可以替换为constexpr std::size_t matrixSize = N;,因为N是编译期已知的模板参数,无需运行时调用size()方法,效率更高。


内容的提问来源于stack exchange,提问作者eccentricOrange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:47:30