Search code examples
c++operator-overloadingcomma-operator

How to overload a comma operator to assign values to an array


So I've got the following code:

#include <map>
#include <iostream>
using namespace std;

template<class V, unsigned D>
class SparseArray
{
public:

    map<string,V> data;

    SparseArray(){}

    class Index
    {
    private:
        int dims[D]{};
    public:
        int& operator[](int index)
        {
            return dims[index];
        }

        const int& operator[](int index) const
        {
            return dims[index];
        }

        friend ostream& operator<<(ostream& os, const SparseArray<V,D>::Index& index)
        {
            os << '{';
            for(int i=0;i<D;i++)
            {
                os<<index.dims[i];
                if(i+1!=D)os<<',';
            }
            os << '}';
            return os;
        }
        Index operator,(Index index)
        {

        }

        Index(){for(int i=0;i<D;i++){dims[i]=0;}}
    };

};

int main()
{
SparseArray<int,3>::Index i;

i[0] = 1;
i[1] = 2;
i[2] = 7;

//i = 1,2,7; - that's what i'm trying to make work

cout<<i;
}

How do I implement the comma operator so that i=1,2,7 will do the exact same thing as doing i[0] = 1; i[1] = 2; i[2] = 7; What i know so far is that i=1,2,7 is equivalent to i.operator=(1).operator,(2).operator,(7); , how do i use this? I know from research that overloading comma operator is unusual, yet i need to do it as it's in the requirements of the project.


Solution

  • How do I implement the comma operator so that obj = 1, 2, 7 will do the exact same thing as doing obj.arr[0] = 1; obj.arr[1] = 2; obj.arr[2] = 7;?

    This would completely change the meaning of comma operator. I will prefer initializer list:

    obj = {1, 2, 7};
    

    over the usage of comma operator in this scenario.

    I know from research that overloading comma operator is unusual, yet I need to do it as it's in the requirements of the project.

    Yes, I have met such teachers. I think they just want to test whether you can crack their task under these strange constraints. And my solution is based on the hidden clue in your question itself.

    What I know so far is that obj = 1, 2, 7 is equivalent to obj.operator=(1).operator,(2).operator,(7);

    Exactly. Notice how operator, is almost synonymous to operator= in this task:

    obj.operator=(1).operator=(2).operator=(7);
    

    So, it's just a matter of implementing this trick:

    Sample& Sample::operator,(const int& val)
    {
        // simply reuse the assignment operator
        *this = val;
    
        // associativity of comma operator will take care of the rest
        return *this;
    }
    

    Implementing operator= is upto you.

    Then you can do

    obj = 1, 2, 7;
    

    I've made a small working code similar to your example: Live Demo.

    Edit:

    Following Jarod's comment, which proposes a more reasonable overloading of these operators, you can overload operator= in this way (clear + push_back):

    Sample& Sample::operator=(const int& val)
    {
        arr[0] = val;
        length = 1;
        return *this;
    }
    

    And operator, in this way (push_back):

    Sample& Sample::operator,(const int& val)
    {
        // append the value to arr
        arr[length] = val;
        ++length;
    
        // associativity of comma operator will take care of the rest
        return *this;
    }
    

    Putting this idea together: Demo 2