英文:
Argument mismatch when there doesn't seem to be any
问题
下面是您提供的代码的中文翻译:
我正在尝试编写一个程序来找到一个N×N矩阵的行列式,并在此过程中首次了解`std::array`和`模板`。
我基于代数余子式和子矩阵的方法提出了这个实现。
```c++
#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("期望方阵");
}
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("行列式 = %.2f\n", getDeterminant(matrix));
}
然而,当我运行make
时,我得到一个错误,我无法解决。应该如何继续?
vscode ➜ /workspaces/c-cpp-mirror/11032023-arrays $ make determinant
g++ determinant.cpp -o determinant
determinant.cpp: 在函数‘int main(int, const char**)’中:
determinant.cpp:68:57: 错误:没有找到与‘getDeterminant(Matrix<3>&)’匹配的函数调用
68 | printf("行列式 = %.2f\n", getDeterminant(matrix));
| ^
determinant.cpp:31:8: 注意:候选函数:‘template<int N> double getDeterminant(Matrix<N>)’
31 | double getDeterminant(Matrix<N> matrix) {
| ^~~~~~~~~~~~~~
determinant.cpp:31:8: 注意:模板参数推断/替代失败:
determinant.cpp:68:57: 注意:类型不匹配‘int’和‘long unsigned int’
68 | printf("行列式 = %.2f\n", getDeterminant(matrix));
| ^
make: *** [<内置>: determinant] 错误 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);
}
希望这些翻译有助于您理解代码中的问题。如果您需要进一步的帮助,请告诉我。
英文:
I'm trying to write a program to find the determinant of an NxN matrix, and in doing so, learning about std::array
and templates
for the first time.
I came up with this implementation, based on the method of cofactors and minor.
#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));
}
However, when I run make
, I get an error I'm not quite able to resolve. How to proceed?
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
Here's a smaller program that still exhibits the same behaviour:
#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
得分: 4
以下是已经翻译好的部分:
首先,代码中存在多个基本问题。
第一个问题是std::array
的第二个模板参数不是int
,而是std::size_t
。
将这个事实与using
别名一起放入混合器中,搅拌一下,实际上就是要求一个受苦的C++编译器从size_t
中推断出一个int
。这是一个苹果与橙子的问题。
要解决这个问题,必须将所有模板template<int N>
声明更改为template<size_t n>
。
但是当发生这种情况时,您的编译器会感到不高兴,因为您将指示您受苦的C++编译器创建一个具有比宇宙中存在的原子更多值的矩阵:
else if (matrixSize > 0) {
Matrix<N - 1> temp;
当Matrix
为0时,这将最终成为一个相当大的矩阵,不是吗?即使不会采取这个分支,这仍然需要编译,作为模板,您受苦的C++编译器需要基本上对其进行评估。这样的机会并不是很有可能。
所以,您需要修复它,将所有这些更改为if constexpr
。
然后,代码将能够编译。
#include <array>
#include <iostream>
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;
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 <std::size_t N>
double getDeterminant(Matrix<N> matrix) {
static const int matrixSize = matrix.size();
double determinant;
if constexpr (matrixSize == 1) {
determinant = matrix[0][0];
}
else if constexpr (matrixSize == 2) {
determinant = (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
}
else if constexpr (matrixSize > 0) {
Matrix<N - 1> temp;
int sign = 1;
for (size_t dimension = 0; dimension < N; dimension++) {
temp = subMatrix(matrix, 0, dimension);
determinant += sign * matrix[0][dimension] * getDeterminant(temp);
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));
}
英文:
There are multiple fundamental issues with the shown code.
The first one is thatstd::array
's 2nd template parameter is not an int
. It's a std::size_t
.
Put this fact in a blender, together with a using
alias, swirl it around, and you end up in, basically, asking a suffering C++ compiler to deduce an int
from a size_t
. It's an apple vs oranges problem.
To fix this first problem, all template template<int N>
declarations must be changed to template<size_t n>
.
But when this happens your compiler will be grumpy, because you will be instructing your suffering C++ compiler to create a matrix with more values than there are atoms in our shared universe:
else if (matrixSize > 0) {
Matrix<N - 1> temp;
When Matrix
is 0 this will end up being a pretty large Matrix, won't you say? Even though this branch will not be taken, this still has to compile, and as a template your suffering C++ compiler needs to, basically, evaluate it. The chances of that are not very likely.
So, you need to fix that, and change all of these to if constexpr
.
Then, the code will compile.
#include <array>
#include <iostream>
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;
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 <std::size_t N>
double getDeterminant(Matrix<N> matrix) {
static const int matrixSize = matrix.size();
double determinant;
if constexpr (matrixSize == 1) {
determinant = matrix[0][0];
}
else if constexpr (matrixSize == 2) {
determinant = (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
}
else if constexpr (matrixSize > 0) {
Matrix<N - 1> temp;
int sign = 1;
for (size_t dimension = 0; dimension < N; dimension++) {
temp = subMatrix(matrix, 0, dimension);
determinant += sign * matrix[0][dimension] * getDeterminant(temp);
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));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论