Если не ошибаюсь, то перегружаешь операцию индексирования [], которая возвращает адрес массива, в котором хранятся данные. Второй оператор возьмет элемент, отсчитав соответствующее их количество от возвращенного адреса. Т.е. перегруженный оператор как бы вернет адрес строки, а второй, неперегруженный возьмет из нее элемент.
template
class Matrix
{
public:
class IndexerHelper
{
public:
Real & operator[]( int j ) { return m.data[i*M+j]; }
private:
friend class Matrix;
IndexerHelper( Matrix & mm, int ii ) : i(ii), m(mm) {}
Matrix & m;
int i;
};
class ConstIndexerHelper
{
public:
const Real & operator[]( int j ) const { return m.data[i*M+j]; }
private:
friend class Matrix;
ConstIndexerHelper( const Matrix & mm, int ii ) : i(ii), m(mm) {}
const Matrix & m;
int i;
};
const ConstIndexerHelper operator[](int i) const { return ConstIndexerHelper( *this, i ); }
IndexerHelper operator[](int i) { return IndexerHelper( *this, i ); }
private:
friend class IndexerHelper;
Real data[N*M];
};
int main(int argc, char * argv[])
{
using namespace std;
Matrix m;
m[0][2] = 2;
const Matrix & cm = m;
cout