2014-12-26 3 views
2

Я хочу создать оператор [] в случае двумерного вектора. После поиска я обнаружил, что невозможно передать два аргумента. Как я могу получить значение m_matrix[i][j] в основном?Оператор [] в двумерном векторе

соответствующий код:

class MyMatrix 
{ 
    public:   // Methods 

     MyMatrix(); 
     ~MyMatrix(); 

     int operator[] (int n); 

    private:   // Attributes 

     int m_n; 
     int m_m; 

     std:: vector <std:: vector <int> > m_matrix; 

}; 

int MyMatrix::operator[](int n, int m) // in the cpp 
{ 
    if (n>=0 && m>=0 && n<=m_n && m<=m_m) 
    { 
     return m_matrix[n-1][m-1]; 
    } 
    else 
    { cout<<"******************"<<endl; 
     cout<<"No valid index"<<endl; 
     cout<<"******************"<<endl; 
     return 0; 
    } 
} 

... 

mat_test1[2][2]; // for example in the main 

Что случилось с этим?

+2

'operator []' может принимать только один аргумент, период. Вы можете использовать 'operator()' или иметь 'operator []' вернуть прокси-сервер, реализующий сам 'operator []'. –

+0

Вместо этого вы можете использовать 'operator() (size_t, size_t)'. – juanchopanza

+0

Как насчет 'std :: vector & operator [] (int n);'? –

ответ

1

Чтобы возобновить комментарий, вы можете сделать:

class MyMatrix 
{ 
public: 

    // Other methods 

    const std::vector<int>& operator[] (int m) const { return m_matrix.at(m); } 
    std::vector<int>& operator[] (int m) { return m_matrix.at(m); } 

    int operator() (int m, int n) const { return m_matrix.at(m).at(n); } 
    int& operator() (int m, int n) { return m_matrix.at(m).at(n); } 

private: 
    std::vector<std::vector<int>> m_matrix; 
}; 

Примечания: Я использовал at вместо [] использовать чек от вектора и поэтому он бросает исключение для отказа от связанного доступа.

И затем использовать его:

MyMatrix matrix(5, 4); // size of the matrix from constructor 

matrix[0][1] = 42; // MyMatrix::operator [] followed by std::vector<int>::operator[] 
matrix(2, 2) = 42; // MyMatrix::operator() (int, int); 

Live example.

+0

Я был бы очень удивлен, что 'at' был подходящим. Вы действительно считаете разумным, чтобы все клиенты могли оправиться от того, что, вероятно, является ошибкой программирования? –

+0

@JamesKanze: Я думаю, что это лучше, чем проверка OP. Но 'assert' будет еще лучше. – Jarod42

+0

Я не заметил проверку ФП. Я согласен, это намного хуже.«Утверждать» - это то, что требуется. –

1

Существует несколько способов, но в конце концов все они сводятся к использованию прокси-сервера .

По разным причинам обычная реализация матрицы не std::vector<std::vector<T>>, а просто std::vector<T>, с соответствующего расчета индекса. В этом случае:

class Matrix 
{ 
    int myRows; 
    int myColumns; 
    std::vector<int> myData; 

    class Proxy 
    { 
     Matrix* myOwner; 
     int myRow; 
    public: 
     Proxy(Matrix* owner, int row) 
      : myOwner(owner) 
      , myRow(row) 
     { 
     } 
     int& operator[](int column) 
     { 
      return myOwner->get(myRow, column); 
     } 
    }; 
public: 
    Matrix(int rows, int columns) 
     : myRows(rows) 
     , myColumns(columns) 
     , myData(rows * columns) 
    { 
    } 

    int& get(int row, int column) 
    { 
     assert(0 <= row && row < myRows 
       && 0 <= column && column < myColumns); 
     return myData[ row * myColumns + column ]; 
    } 

    Proxy operator[](int row) { return Proxy(this, row); } 
}; 

В самом деле, вы хотите еще несколько перегруженных (и, возможно, два прокси) на ручки сопзЬ и неконстантные перегрузки. Но это общий шаблон для таких вещей.

Имейте в виду, что существуют два соглашения относительно таких перегрузок. Одним из них является сказать, что [] возвращает проекцию, и что правильное решения для обработки индексации в многомерные структуры является перегрузкой operator() (который может быть выполнен, чтобы принимать произвольное число параметров ). Я лично предпочитаю решение [][], но это предпочтение не универсально; много людей с более математическим фоном предпочитают использовать ().

+0

Можете ли вы объяснить мне, что такое прокси-сервер, пожалуйста? (Я новичок начинаю жаль) – Laura

+0

@Laura Прокси - это именно то, что я показал; класс, который стоит вместо другого, чтобы предложить дополнительную функциональность. Два наиболее часто используемых использования (я думаю) поддерживают несколько '[]', как здесь, и моделируют перегрузку по типу возврата. –

Смежные вопросы