operator[] return type



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef MATRIX_H
#define MATRIX_H

#include <vector>
using namespace 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 ]?

Last edited on
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?
Last edited on
Topic archived. No new replies allowed.