gpt4 book ai didi

c++ - 模板参数推导出错

转载 作者:行者123 更新时间:2023-11-28 00:26:06 32 4
gpt4 key购买 nike

我在这里要完成的是计算某个 NxN 矩阵的行列式。行列式定义如下:

det <strong>M</strong> = M<sub>ik</sub>C<sub>ik</sub>(<strong>M</strong>) ,其中 i 从 1 到 N 循环,k 是任意选择的常数,使得 1 <= k <= N

“C”是辅助因子,定义如下:

C<sub>ij</sub>(<strong>M</strong>) = (-1)<sup>i + j</sup> det <strong>M</strong><sup>{i, j}</sup> ,其中 M{i, j} 表示 (N-1)x(N-1) 矩阵,其条目由 M 在删除第 i 行和第 j

之后

现在,这是我的代码:

template <typename T, const int N>
T determinant(const TMatrixNxM<T, N, N> &par_value)
{
T result = T(0);

switch (N)
{
case 1:
//Hardcoded for 1x1 matrix:
result = par_value[0][0];
break;
case 2:
//Hardcoded for 2x2 matrix:
result = par_value[0][0] * par_value[1][1] - par_value[0][1] * par_value[1][0];
break;
case 3:
//Hardcoded for 3x3 matrix:
result = par_value[0][0] * (par_value[1][1] * par_value[2][2] - par_value[1][2] * par_value[2][1]) - par_value[0][1] * (par_value[1][0] * par_value[2][2] - par_value[1][2] * par_value[2][0]) + par_value[0][2] * (par_value[1][0] * par_value[2][1] - par_value[1][1] * par_value[2][0]);
break;
default:
//i loops through 0 to N-1, k is arbitrarily chosen to be 0
for (int i = 0; i < N; i++)
{
result += par_value[i][0] * cofactor(par_value, i, 0);
}
break;
}

return result;
}

template <typename T, const int N>
T cofactor(const TMatrixNxM<T, N, N> &par_value, int par_i, int par_j)
{
T result = T(0);

//Construct the new matrix, without the i-th row j-th column
TMatrixNxM<T, N - 1, N - 1> newMatrix;

int k = 0;

for (int i = 0; i < N - 1; i++)
{
int l = 0;

if (k == par_i) k++;

for (int j = 0; j < N - 1; j++)
{
if (l == par_j) l++;

newMatrix[i][j] = par_value[k][l];

l++;
}

k++;
}

result = pow(-1, (par_i + 1) + (par_j + 1)) * determinant(newMatrix); //I have to add +1 to i and j since I started from 0

return result;
}

并测试它:

TMatrixNxM<float, 3, 3> mat1;
//Set values
float det = determinant(mat1);

但是,编译器给我这些错误:
警告 3 警告 C4200:使用了非标准扩展:结构/union 中的零大小数组
错误4错误C2118:负下标
它指的是保存矩阵值的数据数组

当我看到编译器输出的其余部分时,我发现它正在尝试推导 N 设置为 0 甚至 -1 的参数。这里发生了什么?显然,它不应该走那么远(实际上,正如我所见,它不应该低于 3)。

此外,如果我在余因子函数中注释掉对行列式函数的递归调用,它会编译(它也会正确计算新矩阵)。或者,如果我注释掉行列式函数中的整个“默认”部分,它会编译(并且它也会正确计算硬编码的行列式)。

谢谢你的时间

编辑 1

注释中请求的代码,显示数据数组的声明:

template <typename T, const int N, const int M>
class TMatrixNxM
{
public:
TMatrixNxM(T = T(0));
//Other things
protected:
TVectorND<T, M> data[N];
};

template <typename T, const int N>
class TVectorND
{
public:
TVectorND(T = T(0));
//Other things
protected:
T data[N];
};

最佳答案

即使实际上没有达到代码,编译器也需要能够编译整个行列式。因此,即使对于 N = 3,您仍然需要能够使用 N = 3 调用 cofactor,后者又调用 N = 2 行列式。反过来,这需要能够调用 cofactor with N = 2determinant with N = 1,等等上,直到到达 N = -1 和编译错误。

不要在行列式切换N,而是使用重载模板:

template <typename T>
T determinant(const TMatrixNxM<T, 1, 1> &par_value)
{
T result = T(0);
result = par_value[0][0];
return result;
}

template <typename T>
T determinant(const TMatrixNxM<T, 2, 2> &par_value)
{
T result = T(0);
result = par_value[0][0] * par_value[1][1] - par_value[0][1] * par_value[1][0];
return result;
}

template <typename T>
T determinant(const TMatrixNxM<T, 3, 3> &par_value)
{
T result = T(0);
result = par_value[0][0] * (par_value[1][1] * par_value[2][2] - par_value[1][2] * par_value[2][1]) - par_value[0][1] * (par_value[1][0] * par_value[2][2] - par_value[1][2] * par_value[2][0]) + par_value[0][2] * (par_value[1][0] * par_value[2][1] - par_value[1][1] * par_value[2][0]);
return result;
}

template <typename T, const int N>
T determinant(const TMatrixNxM<T, N, N> &par_value)
{
static_assert(N >= 4, "Default determinant called for N<4");
T result = T(0);

//i loops through 0 to N-1, k is arbitrarily chosen to be 0
for (int i = 0; i < N; i++)
{
result += par_value[i][0] * cofactor(par_value, i, 0);
}
return result;
}

Demo .

关于c++ - 模板参数推导出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24987240/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com