c++ two versions of overloading subscript operator

Simon Righley picture Simon Righley · Mar 14, 2013 · Viewed 10.9k times · Source

My question is about the difference between:

const T& operator[](const int nIndex) const;

and:

T& operator[](const int nIndex);

Why would I need both of them defined in a class, what's the purpose? Wouldn't the latter suffice?

Answer

Joseph Mansfield picture Joseph Mansfield · Mar 14, 2013

A member function declaration with const at the end of it allows that function to be called even on a const object. This only makes sense for member functions that don't modify the state of the object.

Let's say the class you have that overloads these operators is called X. Presumably it behaves a bit like a container, giving access to the elements it contains through this operator[].

Now let's say the user wants to use a const X:

const X x = /* fill it */;
use(x[0]);

Should the user be allowed to do this? Probably. If they want a container that is immutable, then let them have it. If you didn't provide the const version of operator[], they wouldn't be able to do this. They're not trying to modify the container after all, they're just looking at its contents.

Now why make the const version of operator[] return a const reference? Because it has to. It's returning a reference to a member of the class itself. If the container was const and returned a non-const reference, the caller would be able to modify its internals just by using this operator:

const X x = /* fill it */;
x[0].modify();

Oh dear, we modify the state of x even though it's const. This would be bad and in fact, the compiler won't even let you do it.