参数不匹配,似乎没有任何匹配

huangapple go评论65阅读模式
英文:

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 &lt;array&gt;
#include &lt;iostream&gt;

template &lt;int N&gt;
using Matrix = std::array&lt;std::array&lt;double, N&gt;, N&gt;;

template &lt;int N&gt;
Matrix&lt;N - 1&gt; subMatrix(Matrix&lt;N&gt; matrix, size_t focusRow, size_t focusColumn) {
    Matrix&lt;N - 1&gt; returnMatrix;

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

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

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

    return returnMatrix;
}

template &lt;int N&gt;
double getDeterminant(Matrix&lt;N&gt; 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 &gt; 0) {
        int sign = 1;

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

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

    return determinant;
}

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

    Matrix&lt;length&gt; matrix = {{{1, 2, 3},
                              {4, 5, 6},
                              {7, 8, 9}}};

    printf(&quot;determinant = %.2f\n&quot;, 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&lt;3&gt;&amp;)   68 |     printf(&quot;determinant = %.2f\n&quot;, getDeterminant(matrix));
      |                                                         ^
determinant.cpp:31:8: note: candidate: ‘template&lt;int N&gt; double getDeterminant(Matrix&lt;N&gt;)   31 | double getDeterminant(Matrix&lt;N&gt; 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(&quot;determinant = %.2f\n&quot;, getDeterminant(matrix));
      |                                                         ^
make: *** [&lt;builtin&gt;: determinant] Error 1

Here's a smaller program that still exhibits the same behaviour:

#include &lt;array&gt;
#include &lt;iostream&gt;

template &lt;int N&gt;
using Matrix = std::array&lt;std::array&lt;double, N&gt;, N&gt;;

template &lt;int N&gt;
void printMatrix(Matrix&lt;N&gt; matrix) {}

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

    Matrix&lt;length&gt; 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&lt;int N&gt; declarations must be changed to template&lt;size_t n&gt;.

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 &gt; 0) {
Matrix&lt;N - 1&gt; 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 &lt;array&gt;
#include &lt;iostream&gt;
template &lt;std::size_t N&gt;
using Matrix = std::array&lt;std::array&lt;double, N&gt;, N&gt;;
template &lt;std::size_t N&gt;
Matrix&lt;N - 1&gt; subMatrix(Matrix&lt;N&gt; matrix, size_t focusRow, size_t focusColumn) {
Matrix&lt;N - 1&gt; returnMatrix;
int subMatrixRow = 0, subMatrixColumn = 0;
static const int matrixSize = matrix.size();
for (size_t matrixRow = 0; matrixRow &lt; matrixSize; matrixRow++) {
for (size_t matrixColumn = 0; matrixColumn &lt; matrixSize; matrixColumn++) {
if (matrixRow != focusRow &amp;&amp; matrixColumn != focusColumn) {
returnMatrix[subMatrixRow][subMatrixColumn++] = matrix[matrixRow][matrixColumn];
if (subMatrixColumn == matrixSize - 1) {
subMatrixColumn = 0;
subMatrixRow++;
}
}
}
}
return returnMatrix;
}
template &lt;std::size_t N&gt;
double getDeterminant(Matrix&lt;N&gt; 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 &gt; 0) {
Matrix&lt;N - 1&gt; temp;
int sign = 1;
for (size_t dimension = 0; dimension &lt; N; dimension++) {
temp = subMatrix(matrix, 0, dimension);
determinant += sign * matrix[0][dimension] * getDeterminant(temp);
sign = -sign;
}
}
else {
throw std::invalid_argument(&quot;expected square matrix&quot;);
}
return determinant;
}
int main(int argc, char const* argv[]) {
static const int length = 3;
Matrix&lt;length&gt; matrix = {{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}};
printf(&quot;determinant = %.2f\n&quot;, getDeterminant(matrix));
}

huangapple
  • 本文由 发表于 2023年3月12日 19:35:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定