Tutorial :trying to make a simple grid-class, non-lvalue in assignment



Question:

I'm implementing a simple C++ grid class. One Function it should support is accessed through round brackets, so that I can access the elements by writing mygrid(0,0). I overloaded the () operator and i am getting the error message: "non-lvalue in assignment".

what I want to be able to do:

//main    cGrid<cA*> grid(5, 5);    grid(0,0) = new cA();  

excerpt of my implementation of the grid class:

template class cGrid {

private:      T* data;      int mWidth;      int mHeight;    public:      cGrid(int width, int height) : mWidth(width), mHeight(height) {           data = new T[width*height];       }        ~cGrid() { delete data; }        T operator ()(int x, int y)      {          if (x >= 0 && x <= mWidth) {              if (y >= 0 && y <= mHeight) {                  return data[x + y * mWidth];              }          }      }          const T &operator ()(int x, int y) const      {          if (x >= 0 && x <= mWidth) {              if (y >= 0 && y <= mHeight) {                  return data[x + y * mWidth];              }          }      }  

The rest of the code deals with the implementation of an iterator and should not be releveant.


Solution:1

As Bill remarked, the operator shouldn't be const. I believe this is the reason for the compilation error (even if the error reported seems different). The compiler only encounters the error at the assignment line because it is a template class.

To be clear, you can't have a const method return a reference to a non-const. I.e., the problem is that the declaration T &operator... const is illegal. It should be either T &operator... or const T &operator... const. Of course you can have both.

Edit: Removing the const doesn't help because now both methods have the same signature (the return type is not considered part of the signature for purposes of resolving the call). The method being called is the one returning T, not T &. Get rid of it (or replace it with a const method returning a const reference.)


Solution:2

What does this template:

 T &operator ()(int x, int y) const  {      if (x >= 0 && x <= mWidth) {          if (y >= 0 && y <= mHeight) {              return data[x + y * mWidth];          }      }  }  

do if x & y are out of range? You should raise an exception. And how are you allocating memory to the grid in the constructor? As regards constness, you need to supply two versions of this operator - a const one that returns a const reference, and a non-const one that returns a non-const reference.

Edit: You also have an off-by one error in the operator. This compiles and runs:

template <typename T>  struct Grid {      Grid( int x, int y ) : mX(x), mY(y), mData(0) {        mData = new T[ x * y ];      }        ~Grid() {        delete [] mData;      }        T &operator ()(int x, int y)  {          if (x >= 0 && x < mX) {              if (y >= 0 && y < mY) {                  return mData[x + y * mX];              }          }      throw "out of range" ;;      }        int mX, mY      T * mData;  };      int main() {      Grid <int> g(2,3);      g(0,0) = 42;  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »