More C++ Idioms/Temporary Proxy

= Temporary Proxy =

Intent
To detect and execute different code when the result of overloaded  is either modified or observed.

Also Known As
proxy

Motivation
The index operator is often used to provide array like access syntax for user-defined classes. C++ standard library uses  in std::string and std::map classes. Standard string simply returns a character reference as a result of  whereas std::map returns a reference to the value given its key. In both cases, the returned reference can be directly read or written to. The string or map class have no knowledge or has no control over whether the reference is used for reading or for modification. Sometimes, however, it is useful to detect how the value is being used.

For example, consider an  class, which supports a single undo operation in addition to the existing std::string interface. The design must allow an undo even though the character is accessed using the index operator. As mention above, std::string class has no knowledge of whether the result of  will be written to or not. The temporary proxy can be used to solve this problem.

Solution and Sample Code
The temporary proxy idiom uses another object, conveniently called proxy, to detect whether the result of  is used for reading or writing. The  class below defines its own non-const , which takes place of std::string's non-const. The new  returns an object of   type. The  type defines an overloaded assignment operator and a conversion operator. Depending on the context how the proxy is used, the compiler chooses different functions as shown below.

In all the output expressions above, the   object is used for reading and therefore, the compiler uses the conversion operator, which simply returns the underlying character. In the assignment statement, however, the compiler invokes the assignment operator of the  class. The assignment operator of the  object saves the original character value in the parent   object and finally writes the new character value to the new position. This way, using an extra level of indirection of a temporary proxy object the idiom is able to distinguish between a read and a write operation and take different action based on that.

Caveats

Introducing an intermediary  may result in surprising compiler errors. For example, a seemingly innocuous function  fails to compile using the current definition of the   class. The compiler is unable to find a conversion operator that converts the temporary proxy object into a. We have defined only a  conversion operator that returns a. To allow the program to compile, another non-const conversion operator could be added. However, as soon as we do that, it is not clear whether the result of conversion is used to modify the original or not.