Перегрузка с двумя квадратными скобками

я пишу матричный класс в С++ и перегружал некоторый оператор типа = и → и <,... но я не могу перегрузить оператор [] [] для класса матрицы. если у меня есть объект матрицы классов, такой как M1, то я могу использовать этот способ для предоставления значения каждому элементу:

M1[1][2]=5;

ИЛИ

int X;

X=M1[4][5];

Ответ 1

Просто перегрузите operator[] и верните указатель на соответствующую строку или столбец матрицы. Так как указатели поддерживают подпитку с помощью [], тогда возможен доступ к "двойному квадрату" нотации [][].

Вы также можете перегрузить operator() двумя аргументами.

Ответ 2

В С++ нет operator[][]. Вы должны return вспомогательный объект, а затем перегружать operator[] для этого, чтобы иметь такой доступ.

Ответ 3

нет operator[][], вы можете реализовать operator[], чтобы вернуть ссылку на объект row/column, в котором вы можете реализовать operator[], чтобы вернуть вам ссылку на ячейку.

Вы можете сделать что-то вроде следующего, чтобы избежать всего, что хлопот..

struct loc
{
  int x;
  int y;
};

то в вашей перегрузке operator[], примите loc, что-то вроде

T& operator[](loc const& cLoc)
{
 // now you have x/y you can return the object there.
}

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

matrix[loc(2,3)] = 5; 

Ответ 4

Вы можете перегрузить operator[]. Поэтому, если вы хотите использовать матрицу таким образом, вы должны сделать матрицу как массив векторов.

class Matrix
{
...
  Vector & operator[]( int index );
...
};

и

class Vector
{
...
  double & operator[]( int index );
...
};

Наконец:

Matrix m;
...
double value = m[i][j];
...

Ответ 5

Собственно, я сделал это только в своем собственном классе матриц несколько лет назад. В этом случае я определил шаблон шаблона матрицы, содержащий ниже фрагмент.

Затем я смог выполнить итерацию и назначить следующее:

          for(size_t k=1; k<n; ++k) {       
                   minor[p][k-1]=major[j][k];        
           }

Надеюсь, это поможет.

// //////////////////////////////////////////////////////////////////////////////
// list is internal vector representation of n x m matrix
T* list;
// Proxy object used to provide the column operator
template < typename T >
class OperatorBracketHelper
{
    Matrix < T > & parent ;
    size_t firstIndex ;

    public :
        OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
        parent ( Parent ), firstIndex ( FirstIndex ) {}

        // method called for column operator
        T & operator []( size_t SecondIndex )
        {
            // Call the parent GetElement method which will actually retrieve the element
            return parent.GetElement ( firstIndex , SecondIndex );
        }
};

// method called for row operator
OperatorBracketHelper < T > operator []( size_t FirstIndex )
{
    // Return a proxy object that "knows" to which container it has to ask the element
    // and which is the first index (specified in this call)
    return OperatorBracketHelper < T >(* this , FirstIndex );
}

T & GetElement ( size_t FirstIndex , size_t SecondIndex )
{
    return list[FirstIndex*cols+SecondIndex];
}

Ответ 6

Вы не можете перегрузить [][] как таковой, так как нет такого оператор. Вы можете перегрузить [], чтобы вернуть что-то, что также имеет на нем [] (прокси); в простейшем случае, что-то вроде double* будет работать, но обычно лучше, хотя немного больше работы, чтобы использовать полный класс. (Место для добавления проверка границ, например.)

В качестве альтернативы вы можете перегрузить (x,y). В зависимости от того, кто вы спросите, один формат или другой "лучше". (На самом деле, это строго вопрос стиля.)

Ответ 7

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

Однако обратите внимание, что индекс, с которым вы взаимодействуете с первым перегруженным оператором [], должен быть где-то сохранен, чтобы вы могли использовать его в последнем перегруженном операторе []. По этой причине я просто добавил новый член типа int в класс Array (который я назвал его "test" в моем коде ниже).

class Array {

private: 

 double **ptr; int test;
 ...   /* the rest of the members includes the number of rows and columns */

public:
    Array(int=3,int=3);  // Constructor
    Array(Array &);      // Copy Constructor
    ~Array();            // Destructor
    void get_array();
    void show_array();
    double* operator[] (int);
    double operator[] (short int);
    ...
};

... 

double* Array::operator[] (int a) {
    test = a;
    double* p = ptr[test];
    return p;
}

double Array::operator[] (short int b) {
   return ((*this)[test][b]);
}

Поэтому, в качестве примера, в основном я могу просто написать:

int main(){
Array example;
cout << example[1][2];  
}

Надеюсь, это поможет вам.