#ifndef MATRIX_H
#define MATRIX_H
#include <vector>
usingnamespace std;
template <typename Object>
class matrix
{
public:
matrix( int rows, int cols ) : array( rows )
{
for( auto & thisRow : array )
thisRow.resize( cols );
}
matrix( vector<vector<Object>> v ) : array{ v }
{ }
matrix( vector<vector<Object>> && v ) : array{ std::move( v ) }
{ }
const vector<Object> & operator[]( int row ) const
{
return array[ row ];
}
vector<Object> & operator[]( int row )
{
return array[ row ];
}
int numrows( ) const
{
return array.size( );
}
int numcols( ) const
{
return numrows( ) ? array[ 0 ].size( ) : 0;
}
private:
vector<vector<Object>> array;
};
#endif
1 2 3 4 5
void copy( const matrix<int> & from, matrix<int> & to )
{
for( int i = 0; i < to.numrows( ); ++i )
to[ i ] = from[ i ];
}
In the copy function, we attempt to copy each row in matrix from into the corresponding row in matrix to. Clearly, if operator[] returns a constant reference, then to[i] cannot appear on the left side of the assignment statement. Thus, it appears that operator[] should return a reference. However, if we did that, then an expression such as from[i]=to[i] would compile, since from[i] would not be a constant vector, even though from was a constant matrix. That cannot be allowed in a good design.
The above quote is from my textbook.
I am not understanding the bolded part. Why would return by reference for operator[] cause to[ i ] = from[ i ] to change to from[ i ] = to[ i ]?
In to[ i ] = from[ i ];
the to[ i ] has to call line 28, because the reference cannot be const and
the from[ i ] has to call line 23, because the from is const.
Put other way, the line 23 has to return const reference (or by value), but line 28 has to return a reference. The const and non-const versions of the member function do not return exactly the same thing.
What they try to say is that if the line 23 would return a non-const reference, then the const from could be on the left side of the assignment, which is a logical error.
What they try to say is that if the line 23 would return a non-const reference, then the const from could be on the left side of the assignment, which is a logical error.
Oh, so they're just saying that from[ i ] = to[ i ] could compile, not that it will compile. They don't want from matrix to be changed, but because the row vector returned by operator[] is not a const, you could still change the vector in from. I get it now, thanks.
Another thing troubling me is which operator[] does from or to matrices call? Does the left hand side always call the non-const reference and the right hand always call const reference?