我正试着写一个程序来求一个N × N矩阵的行列式,在这个过程中,我第一次了解了std::array
和templates
。
我提出了这个实现,基于辅因子和次因子的方法。
#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);
}
1条答案
按热度按时间ymdaylpp1#
所示代码存在多个基本问题。
第一个是
std::array
的第二个模板参数不是int
,而是std::size_t
。把这个事实和一个
using
别名放在一个搅拌器里,旋转它,你最终会要求一个痛苦的C编译器从size_t
推导出int
,这是一个苹果对桔子的问题。要解决第一个问题,必须将所有模板
template<int N>
声明更改为template<size_t n>
。但是,当这种情况发生时,你的编译器会很生气,因为你将指示你的痛苦的C编译器创建一个矩阵,其值比我们共享宇宙中的原子还要多:
当
Matrix
为0时,这将是一个相当大的矩阵,你不觉得吗?即使这个分支不会被采用,它仍然需要编译,作为一个模板,你的C++编译器基本上需要计算它。因此,您需要修复它,并将所有这些更改为
if constexpr
。然后,代码将编译。