模板参数推断出错了

时间:2014-07-28 01:05:06

标签: c++ templates matrix arguments

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

det M = MikCik(M),其中 i 从1到N循环而 k 是任意选择的常数,使得1 <= k <= N

&#34; C&#34;是辅助因子,定义如下:

Cij(M) = (-1)i + j det M{i, j},其中 M {i,j} 表示(N-1)x(N-1)矩阵,其条目由原始值组成删除 i -th行和 j -th列后 M 的条目

现在,这是我的代码:

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:使用非标准扩展:struct / union中的零大小数组 错误4错误C2118:否定下标
它指的是包含矩阵值的数据数组

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

另外,如果我在辅助因子函数中注释掉对行列式函数的递归调用,它会编译(它也会正确计算新矩阵)。或者,如果我注释掉整个&#34;默认&#34;在部分决定函数中,它编译(并且它也正确计算硬编码的决定因素)。

感谢您的时间

编辑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];
};

1 个答案:

答案 0 :(得分:3)

即使代码没有实际到达,编译器也需要能够编译整个determinant。因此,即使对于N = 3,您仍然需要能够使用cofactor来呼叫N = 3,而determinant又会使用N = 2来呼叫cofactor。反过来,这需要能够使用N = 2determinantN = 1一起调用N = -1,依此类推,直到您到达switch并出现编译错误。

而不是N determinant 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; } ,而是使用重载模板:

{{1}}

Demo