Home > database >  C constructor or recursive member function when using templates
C constructor or recursive member function when using templates

Time:11-01

I am writing a matrix library, and when I tested the determinant of the matrix, I found this error

I rarely use templates and can’t find the reason for the error

template<int n>
struct Vec{
    double data[n]{0};
    Vec() = default;
    explicit Vec(int value) { ... }
};

template<int row, int col>
struct Mat{
    Vec<col> data[row];
    explicit Mat() { ... }
    Mat(std::initializer_list<double> list) { ... }

    Mat<row - 1, col - 1> Minor(const int x, const int y) const{
        Mat<row - 1, col - 1> ret;
        ...
        return ret;
    }

    double Cofactor(const int x, const int y) const{
        return Minor(x, y).Det() * ((x   y) % 2 ? -1 : 1);
    }

    double Det() const{
        assert(row == col);
        if(row == 1 && col == 1) return data[0][0];
        double ret = 0;
        for(int i = 0; i < col;   i){
            ret  = data[0][i] * Cofactor(0, i);
        }
        return ret;
    }
};

Unable to call Det

Mat<3, 3> matrix{2, 6, 3,
                 1, 0, 2,
                 5, 8, 4};
std::cout << matrix.Det() << std::endl;

The error message is as follows enter image description here

CodePudding user response:

If your compiler supports at least C 17, then the solution is using if constexpr:

double Det() const{
        static_assert(row == col);
        if constexpr(row == 1 && col == 1) return data[0][0];
        else
        {
            double ret = 0;
            for(int i = 0; i < col;   i){
                ret  = data[0][i] * Cofactor(0, I);
            }
            return ret;
        }
    }

This is C aspect of it. From an algorithmic perspective, computing determinants by definition (i.e. using the Kronecker method), as you do, leads to exponential complexity as a function of matrix size. Algorithms exist that are only a cube of matrix size.

  • Related