Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading the C++ indexing subscript operator [] in a manner that allows for responses to updates

Consider the task of writing an indexable class which automatically synchronizes its state with some external data-store (e.g. a file). In order to do this the class would need to be made aware of changes to the indexed value which might occur. Unfortunately the usual approach to overloading operator[] does not allow for this, for example...

Type& operator[](int index) {     assert(index >=0 && index < size);     return state[index]; } 

I there any way to distinguish between a value being accessed and a value being modified?

Type a = myIndexable[2]; //Access myIndexable[3] = a;  //Modification 

Both of these cases occur after the function has returned. Is there some other approach to overloading operator[] which would perhaps make more sense?

like image 400
DuncanACoulter Avatar asked Aug 27 '10 06:08

DuncanACoulter


People also ask

What does overloading the [] operator do?

It allows you to provide an intuitive interface to users of your class, plus makes it possible for templates to work equally well with classes and built-in/intrinsic types. Operator overloading allows C/C++ operators to have user-defined meanings on user-defined types (classes).

Can [] operator be overloaded?

where () is the function call operator and [] is the subscript operator. You cannot overload the following operators: .

How do you overload subscript operators?

Overloading Subscript or array index operator [] in C++ The Subscript or Array Index Operator is denoted by '[]'. This operator is generally used with arrays to retrieve and manipulate the array elements. This is a binary or n-ary operator and is represented in two parts: postfix/primary expression.

Which operator is overloaded for C operation?

Input/Output Operators Overloading in C++ C++ is able to input and output the built-in data types using the stream extraction operator >> and the stream insertion operator <<. The stream insertion and stream extraction operators also can be overloaded to perform input and output for user-defined types like an object.


1 Answers

From the operator[] you can only really tell access.
Even if the external entity uses the non cost version this does not mean that a write will take place rather that it could take place.

As such What you need to do is return an object that can detect modification.
The best way to do this is to wrap the object with a class that overrides the operator=. This wrapper can then inform the store when the object has been updated. You would also want to override the operator Type (cast) so that a const version of the object can be retrieved for read accesses.

Then we could do something like this:

class WriteCheck; class Store {   public:   Type const& operator[](int index) const   {     return state[index];   }    WriteCheck operator[](int index);   void stateUpdate(int index)   {         // Called when a particular index has been updated.   }   // Stuff };  class WriteCheck {      Store&  store;     Type&   object;     int     index;      public: WriteCheck(Store& s, Type& o, int i): store(s), object(o), index(i) {}      // When assignment is done assign     // Then inform the store.     WriteCheck& operator=(Type const& rhs)     {         object = rhs;         store.stateUpdate(index);     }      // Still allow the base object to be read     // From within this wrapper.     operator Type const&()     {         return object;     }    };        WriteCheck Store::operator[](int index) {        return WriteCheck(*this, state[index], index); } 

An simpler alternative is:
Rather than provide the operator[] you provide a specific set method on the store object and only provide read access through the operator[]

like image 83
Martin York Avatar answered Sep 21 '22 14:09

Martin York