1

I have trouble understanding the problem in the title. So there are my two classes, a Vector of 3 doubles and a 2D dynamic Matrix that has a Vector object in every cell. The constructor of Matrix works and does not throw errors. However, when I want to refer to a cell of created Matrix instance in the ostream overload, I'm getting

"no match for 'operator[]' (operand types are 'Matrix' and 'int')"

Why is it OK to use the [][] notation during initialization and not OK later? Is there a moderately straightforward way to fix this? Many thanks!

class Vector{
private:
double x, y, z;

public:
Vector(){
    x = y = z = 0;
}
Vector(int x_, int y_, int z_){
    x = x_;
    y = y_;
    z = z_;
}
friend ostream &operator<< (ostream &wyj, Vector &v);
friend istream &operator>> (istream &wej, Vector &v);
};
    /// ===== MATRIX CLASS CONSISTS OF VECTOR OBJECTS
class Matrix{
private:
Vector ** M;
int row;
int col;

public:
Matrix(int col, int row){
    M = new Vector * [row];
    for(int i = 0; i < row; i++){
        M[i] = new Vector[col];
    }
    for(int i = 0; i < row; i++){
        for(int j = 0; j < col; j++){
            M[i][j] = Vector();
        }
    }
}

friend ostream &operator<< (ostream &wyj, Matrix &M);

};

ostream &operator<< (ostream &wyj, Matrix &M){

for(int i = 0; i < M.row; i++){
    for(int j = 0; j < M.col; j++){
        wyj << M[i][j] << " ";
    }
    wyj<< endl;
}
return wyj;
}

int main(){
    Matrix A(2, 2);
    cout << A[1][1]; // LURD VADAR SAYZ NOOOOOOOOOOOOOOO

}

EDIT: minor typos in << overload method

Martin
  • 43
  • 6
  • You may want to check out [some good C++ materials](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to give you better background of C++. Nonetheless, the reason why you are getting that error is that you did not overload the `operator[](...)` for the `Matrix` class, And its return type must support `[]` as well. – WhiZTiM Jan 14 '17 at 22:46
  • To use `A[1][1]` in `main()`, the `Matrix` class must provide an `operator[]` that returns something which also has an `operator[]`. It doesn't. – Peter Jan 14 '17 at 22:47
  • That I can grasp. But why does the notation itself works when I create the array in the first place? – Martin Jan 14 '17 at 23:01
  • @Martin -- Please consider overloading operator() instead of operator[] for Matrix access. [See this link as to why](https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op). Also, your initial creation of the Matrix is naive. You are calling the allocator `row` times. What if row is 1000? You're calling new 1001 times. [Here is a more efficient way to create your Matrix, and use only 2 calls to new, regardless of the number of rows](http://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c/21944048#21944048) – PaulMcKenzie Jan 15 '17 at 01:14

1 Answers1

3

Why is it OK to use the [][] notation during initialization and not OK later?

In Matrix's constructor M is a Vector**. In main() A is a Matrix. So [][] is ok for a Vector**, but not meaningful (unless defined) for Matrix.

Is there a moderately straightforward way to fix this?

For [][] to work you need to have operator[] defined twice. Once for the first object and once for the object returned by the first operator[].

So in Matrix you could include:

Vector* operator[](size_t index) { return M[index]; }
wally
  • 10,717
  • 5
  • 39
  • 72