Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is it not possible to return a const reference while overloading the [] operator

Let us take this code as an example

#include <iostream>
using namespace std;

struct valStruct {

    double& operator[](int i){return values[i];};       //line 6
    double operator[](int i) const {return values[i];}; //line 7
    double values[4];
};

int main () {
    valStruct vals = {0,1,2,3};
   cout << "Value before change" << endl;
   for ( int i = 0; i < 3; i++ ) {
      cout << "vals[" << i << "] = "<< vals[i] << endl;
   }

   vals[1] = 2.2; // change 2nd element
 
   cout << "Value after change" << endl;
   for ( int i = 0; i < 3; i++ ) {
      cout << "vals[" << i << "] = "<< vals.values[i] << endl;
   }
   return 0;
}

I understand that line 6 (see comment in code) enables the writing (and reading!?) of a value to the index in array values while line 7 only reads that value.

I understand the need of the const declaration in line 7 as preventing changing the value while not intended (although I do not understand how since line 6 exists), but my question is, why cannot I write the line as

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

double& operator[](int i) const {return values[i];}; //line 7

which throws out the error: binding reference of type ‘double&’ to ‘const double’ discards qualifiers.

This also raises the question of why do we need line 7 at all since line 6 exists and can do both writing and reading.

EDIT:

I understand the idea of a const func() const suggested here and I do not understand how this answers my question. I did not understand the mechanism explained by the two answers given.

>Solution :

why do we need line 7 at all since line 6 exists and can do both writing and reading.

We need line 7 to work on const objects. Line 6 can’t be used on const objects of type valStruct. This is because const class objects can only explicitly call const member functions, and the overloaded operator[] in line 6 has not been marked as a const member function. So it can’t be used on const object of type valStruct. Thus, we need line 7 which "marks" the overloaded operator[] as a const member function.


Now, if you change the return type in line 7 to double&, then the problem is that here you’ve overloaded operator[] as a const member function. This means that the data members are also const. And since we cannot bind an "lvalue reference to non-const object", to a const object, we get the mentioned error. For example,

const double d = 43.4;
double& ref = d;//here we'll get the same error

The situation(of why you’re getting the error) is similar to the above given snippet.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading