Const overloaded operator [] function and its call

I define two versions of the operator[] overloaded function in the array class. ptr is a pointer to the first element of an array object.

 int& array::operator[] (int sub) { return ptr[sub]; } 

and

 int array::operator[] (int sub) const { return ptr[sub]; } 

Now, if I define a const object integer1 , the second function can be called ..... but if I create a non-constant object, and then called as shown below:

 cout << "3rd value is" << integer1[2]; 

what function is called here?

+4
source share
2 answers

In your second example, a non-constant version will be called because no conversion is required, and a call that does not require conversion is a better match than one that requires conversion.

Ultimately, however, you have a major problem: you really need a behavior that changes depending on whether you use your object as an rvalue or lvalue, and const does not actually do that. To make it work correctly, you usually want to return the proxy object and overload operator= and operator T for the proxy object:

 template <class T> class myarray { T *ptr; class proxy { T &val; proxy &operator=(proxy const &p); // assignment not allowed. public: proxy(T &t) : val(t) {} operator T() const { return val; } proxy &operator=(T const&t) { val = t; return *this; } }; proxy const operator[](int sub) const { return proxy(ptr[sub]); } proxy operator[](int sub) { return proxy(ptr[sub]); } // obviously other stuff like ctors needed. }; 

Now we get the normal behavior - when /, if our array<int> (or any type) is const, our operator[] const will be used and it will give const proxy . Since its assignment operators are not constants, an attempt to use them will fail (will not compile).

OTOH, if the original array<int> not const, we will get a non-constant proxy, in which case we can use both operator T and operator= , and be able to read and write the value to array<int> .

+2
source

Your version of const should return const int& not int , so the semantics are the same between two functions.

Once you do this, it doesn't matter which one is used. If the const version should be used because your object has a const context, then it will be ... and it does not matter, since you are not trying to change anything. Otherwise, it will use a version not const ... but with the same effect.

+2
source

All Articles