I am creating a class that is similar to a vector. It uses its own algorithm to determine where and how the data is actually stored. From the user’s standpoint, it works just like a normal vector.
Internally, it tries to save memory by not storing duplicate values more than once. If the same value is pushed onto the vector more than once, it does some fancy dance moves with the indices but only stores the actual value once.
When overloading operator[], the index argument is converted to the “real” index so it can access where the data is actually stored.
If the user tries to access an element like so:
int i = svec[8];
The correct element is returned by converting 8 to the “real” index and accessing the correct element.
The problem comes in when the user tries to assign a value like so:
svec[8] = 1;
The value 8 will again be covered to the “real” index and a reference to the element is returned by operator[](). However, multiple indices might be mapping to that element. If I return a reference and allow it to be changed, it will have the undesired side effect of changing the value for other indices.
If I just return the element by value, you won’t be able to assign a value using operator[].
Within operator[](), I would like to know if an operation plans to change the value of the element so I can create a new element, do some more fancy dance moves with the indices, and return a reference to the new element.
Is anything like this possible? If not, it seems like I’m forced to return by value, thereby preventing the user from modifying the values using [].
It would be easy, if the class would have a method
change_elementand everybody is calling this function when changing, isn’t it?Now, the idea is to return a proxy class from
operator[]that does this job for you.There is no overhead, every common compiler should optimize the proxy element away.
This trick is even used in the STL by
vector<bool>. Check this out for a more complete example.