пытаясь сделать простой grid-класс, не имеющий значения в присваивании - PullRequest
0 голосов
/ 11 февраля 2010

Я реализую простой класс сетки C ++. Одна функция, которую она должна поддерживать, доступна через круглые скобки, поэтому я могу получить доступ к элементам, написав mygrid (0,0) Я перегружен оператор (), и я получаю сообщение об ошибке: "не-значение в назначении".

что я хочу сделать:

//main

cGrid<cA*> grid(5, 5);

grid(0,0) = new cA();

выдержка из моей реализации класса сетки:

шаблон класс 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];
            }
        }
    }

Остальная часть кода имеет дело с реализацией итератора и не должна быть релевантной.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2010

Как заметил Билл, оператор не должен быть const. Я считаю, что это является причиной ошибки компиляции (даже если ошибка кажется другой). Компилятор обнаруживает ошибку только в строке присваивания, потому что это класс шаблона.

Чтобы было ясно, вы не можете иметь метод const, возвращающий ссылку на не-const. Т.е. Проблема в том, что объявление T &operator... const является незаконным. Это должно быть либо T &operator..., либо const T &operator... const. Конечно, вы можете иметь оба.

Редактировать: Удаление const не помогает, поскольку теперь оба метода имеют одну и ту же сигнатуру (тип возврата не считается частью сигнатуры в целях разрешения вызова). Вызываемый метод возвращает T, а не T &. Избавьтесь от него (или замените его методом const, возвращающим ссылку const.)

0 голосов
/ 11 февраля 2010

Что означает этот шаблон:

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

делать, если x & y находятся вне диапазона? Вы должны поднять исключение. И как вы распределяете память для сетки в конструкторе? Что касается константности, вам нужно предоставить две версии этого оператора - константную, которая возвращает константную ссылку, и неконстантную, которая возвращает неконстантную ссылку.

Редактировать: у вас также есть одна ошибка в операторе. Это компилирует и запускает:

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;
}
...