Class operators

前端 未结 2 1252
日久生厌
日久生厌 2021-01-29 14:41

I\'m having a problem to make the code:

void main(){
     Matrix c(rows,cols);//rows & cols are int numbers
     c[0][0]=2//the line that I\'m having a probl         


        
相关标签:
2条回答
  • 2021-01-29 15:18

    There are no operator [][], but operator[]. So that one should return something for which you can use [] too (pointer or proxy class).

    In your case, you might simply do:

    double* operator[](int i) { return mat[i]; }
    const double* operator[](int i) const { return mat[i]; }
    

    For more complicated cases, you have to return a proxy class.

    0 讨论(0)
  • 2021-01-29 15:22

    Don't dynamically allocate in two dimensions like that. It's poison for your cache, and completely pointless. I see it all the time and I wish I didn't! Make yourself a nice std::vector<double> of size rows*cols instead.

    Anyway, the trick to permit [width][height] is a proxy class. Have your operator[] return an instance of a class that has its own operator[] to do the second-level lookup.

    Something like this:

    #include <iostream>
    #include <vector>
    
    struct Matrix
    {
        Matrix(const size_t columns, const size_t rows)
           : columns(columns)
           , rows(rows)
           , data(columns*rows, 0)
        {}
    
        size_t index(const size_t x, const size_t y) const
        {
            return x + y*columns;
        }
    
        double& at(const size_t x, const size_t y)
        {
            return data[index(x, y)];
        }
    
        double at(const size_t x, const size_t y) const
        {
            return data[index(x, y)];
        }
    
        template <bool Const>
        struct LookupHelper
        {
            using ParentType = std::conditional_t<Const, const Matrix, Matrix>;
            using ReturnType = std::conditional_t<Const, double, double&>;
    
            LookupHelper(ParentType& parent, const size_t x) : parent(parent), x(x) {}
    
            ReturnType operator[](const size_t y)
            {
                return parent.data[parent.index(x, y)];
            }
    
            const ReturnType operator[](const size_t y) const
            {
                return parent.data[parent.index(x, y)];
            }
    
        private:
            ParentType& parent;
            const size_t x;
        };
    
        LookupHelper<false> operator[](const size_t x)
        {
            return {*this, x};
        }
    
        LookupHelper<true> operator[](const size_t x) const
        {
            return {*this, x};
        }
    
    private:
        const size_t columns, rows;
        std::vector<double> data;
    };
    
    int main()
    {
        Matrix m(42, 3);
        m[15][3] = 1;
        std::cout << m[15][3] << '\n';
    }
    

    (In reality, you'd want to make it moveable and it could doubtlessly be tidied up a bit.)

    Certainly, switching to operator() or a .at(width, height) member function is a lot easier…

    0 讨论(0)
提交回复
热议问题