查找 C++ 二维数组的行列式时出错

Adv*_* GS 2 c++ recursion templates matrix determinants

我正在使用 C++ 和 g++(版本 13.2.1),并且我正在创建一个Determinant<m>接受std::array<std::array<int,m>,m>参数类型并返回该矩阵的行列式的函数。

\n

以下是我写的代码。

\n

行列式:

\n
template <int m>\nint Determinant(std::array<std::array<int,m>,m> arr){\n\n    if(m == 2){\n      return arr[0][0]*arr[1][1] - arr[0][1]*arr[1][0];\n    }else if(m >2){\n      int ans = 0;\n      for(int i =0;i < m;i++){\n        ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1);\n      }\n      return ans;\n    }else{\n      return -1;\n\n    }\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

slc :返回一个切片(不是真正的切片,只是删除一行和一列)

\n
template <int m, int n>\nstd::array<std::array<int,(n-1)>,(m-1)> slc(std::array<std::array<int,n>,m> arr, int i,int j){\n  std::array<std::array<int,(n-1)>,(m-1)> ans;\n\n  for(int x = 0;x < m;x ++){\n    for (int y = 0;y < n;y++){\n      if(y == i || x == j){\n        continue;\n      }\n      ans[x- ( x>j ? 1:0) ][y- ( y>i ? 1:0) ] = arr[x][y];\n    }\n  }\n  return ans;\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我收到的错误附在这里:

\n
matrices.cpp: In instantiation of \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 0]\xe2\x80\x99:\nmatrices.cpp:85:42:   recursively required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]\xe2\x80\x99\nmatrices.cpp:85:42:   required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]\xe2\x80\x99\nmatrices.cpp:98:30:   required from here\nmatrices.cpp:85:51: warning: size of \xe2\x80\x98<anonymous>\xe2\x80\x99 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]\n   85 |         ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1);\n      |                                           ~~~~~~~~^~~~~~~~~~~\nmatrices.cpp:85:51: warning: size of \xe2\x80\x98<anonymous>\xe2\x80\x99 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]\nIn file included from matrices.cpp:2:\n/usr/include/c++/13/array: In instantiation of \xe2\x80\x98struct std::__array_traits<std::array<int, 18446744073709551615>, 18446744073709551615>\xe2\x80\x99:\nmatrices.cpp:85:42:   recursively required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]\xe2\x80\x99\nmatrices.cpp:85:42:   required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]\xe2\x80\x99\nmatrices.cpp:98:30:   required from here\n/usr/include/c++/13/array:55:13: error: size \xe2\x80\x9818446744073709551615\xe2\x80\x99 of array exceeds maximum object size \xe2\x80\x989223372036854775807\xe2\x80\x99\n   55 |       using _Type = _Tp[_Nm];\n      |             ^~~~~\n/usr/include/c++/13/array: In instantiation of \xe2\x80\x98struct std::__array_traits<int, 18446744073709551615>\xe2\x80\x99:\n/usr/include/c++/13/array:109:55:   recursively required from \xe2\x80\x98struct std::array<int, 18446744073709551615>\xe2\x80\x99\nmatrices.cpp:85:42:   recursively required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]\xe2\x80\x99\nmatrices.cpp:85:42:   required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]\xe2\x80\x99\nmatrices.cpp:98:30:   required from here\n/usr/include/c++/13/array:55:13: error: size \xe2\x80\x9818446744073709551615\xe2\x80\x99 of array exceeds maximum object size \xe2\x80\x989223372036854775807\xe2\x80\x99\nmatrices.cpp: In instantiation of \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 0]\xe2\x80\x99:\nmatrices.cpp:85:42:   recursively required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]\xe2\x80\x99\nmatrices.cpp:85:42:   required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]\xe2\x80\x99\nmatrices.cpp:98:30:   required from here\nmatrices.cpp:85:51: error: could not convert \xe2\x80\x98slc<0, 0>(arr, i, 0)\xe2\x80\x99 from \xe2\x80\x98array<array<[...],4294967295>,4294967295>\xe2\x80\x99 to \xe2\x80\x98array<array<[...],18446744073709551615>,18446744073709551615>\xe2\x80\x99\n   85 |         ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1);\n      |                                           ~~~~~~~~^~~~~~~~~~~\n      |                                                   |\n      |                                                   array<array<[...],4294967295>,4294967295>\nmatrices.cpp: In instantiation of \xe2\x80\x98std::array<std::array<int, (n - 1)>, (m - 1)> slc(std::array<std::array<int, n>, m>, int, int) [with unsigned int m = 0; unsigned int n = 0]\xe2\x80\x99:\nmatrices.cpp:85:42:   recursively required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]\xe2\x80\x99\nmatrices.cpp:85:42:   required from \xe2\x80\x98int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]\xe2\x80\x99\nmatrices.cpp:98:30:   required from here\nmatrices.cpp:6:43: warning: size of \xe2\x80\x98ans\xe2\x80\x99 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]\n    6 |   std::array<std::array<int,(n-1)>,(m-1)> ans;\n      |                                           ^~~\nmatrices.cpp:15:10: warning: size of \xe2\x80\x98<anonymous>\xe2\x80\x99 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]\n   15 |   return ans;\n      |          ^~~\nmatrices.cpp:15:10: warning: size of \xe2\x80\x98<anonymous>\xe2\x80\x99 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]\n
Run Code Online (Sandbox Code Playgroud)\n

任何见解将不胜感激。

\n

Jan*_*tke 5

首先,如果存在类型不匹配,则不可能进行推导。与中的int m类型不同,因此您应该使用:mstd::array<int, m>

template <std::size_t m>
Run Code Online (Sandbox Code Playgroud)

其次,模板实例化中存在无限递归,因为您没有使用if constexpr,而只是使用常规if语句。在 中if (m == 2){,如果条件为假,代码块不会被丢弃,它只是变成死代码。这同样适用于else分支机构。

因此,Determinant<2>实例化Determinant<1>、then Determinant<0>、然后Determinant<-1>是编译器错误的地方。要解决此问题,请使用if constexpr

template <std::size_t m>
int Determinant(std::array<std::array<int, m>, m> arr) {
    if constexpr (m == 0) {
        return -1;
    } else if constexpr (m == 1) {
        return arr[0][0];
    } else if constexpr (m == 2) {
        return arr[0][0] * arr[1][1] - arr[0][1] * arr[1][0];
    } else {
        int ans = 0;
        for (std::size_t i = 0; i < m; i++) {
            ans += arr[0][i] * Determinant<m-1>(slc<m, m>(arr, i, 0)) * (i % 2 ? 1 : -1);
        }
        return ans;
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参阅:“if constexpr()”与“if()”之间的区别