Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array Subscripting: returning Reference vs proxy class method

While searching for methods for overloading Subscript('[]') operator for template class, I came across two different techniques.

First Technique:

Overloading the operator [] returning pointer to the container directly, which will allow both reading value and assigning value. A sample implementation of this technique:

template <class T>
class X
{
    int _size;
    T *container;
public:
    X(int sz)
    {
        _size=sz;
        container=new T[sz]();
    }
    ~X()
    {

    }

    T& operator [](int indx)
    {
        return container[indx];
    }

};

With main() as:

int main() {
    X<int> sample(100);
    cout << sample[9] << endl;
    sample[9] = 9;
    cout << sample[9] << endl;
}

Output:

0
9

Second Technique:

Second technique involves declaring a proxy class and overloading the operator = via that class. A sample implementation of this technique:

template <class T>
class X
{
    int _size;
    T *container;
public:
    X(int sz)
    {
        _size=sz;
        container=new T[sz]();
    }
    ~X()
    {

    }

    class Proxy
    {
        int indx;
        X<T> &parent;
    public:
        Proxy(X<T> &p, int x) : parent(p),indx(x)
        {

        }
        void operator =(T assgn)
        {
            parent.container[indx]=assgn;
        }
        operator T const &()
        {
            return parent.container[indx];
        }
        friend class X<T>;//unnecessary line, I know!
    };
    Proxy operator[](int indx)
    {
        return Proxy(*this,indx);
    }

};

With same main() we get same output.

I personally like the second method. But, I really want to compare these two methods. What are the major functional difference of these two techniques. What advantages each of these method have?

like image 430
Shakib Ahmed Avatar asked Feb 02 '26 19:02

Shakib Ahmed


1 Answers

The proxy-based technique you describe can be used if you want to expose a sequence of elements that are not stored as-such (requiring a conversion from and to storage) or that cannot simply be accessed by-reference. An example is std::vector < bool >: it packs eight bools in every byte (one in each bit) in storage. Storing them that way, it is not possible to return a reference to a single such bool, so the index operator returns a "proxy-object" instead to support reading and writing of the contained bools.

If you can return a direct reference to the stored objects, there is no real advantage to wrapping it in a proxy unless you want to restrict the assignment (only allow positive values in the container for example).

like image 71
heinrichj Avatar answered Feb 05 '26 11:02

heinrichj