Subscript operator overloading

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • gvr123
    New Member
    • Apr 2007
    • 6

    #1

    Subscript operator overloading

    Hi all

    This seems to me a peculiar problem, but confounding nonetheless...

    The problem seems to be that an overloaded subscript operator isn't being called unless it is called explicitly

    Code:
    struct myStruct
    {
    	myStruct& operator[] (int index)
    	{	
    		return *(this + index);
    	}
    
    	bool val1;
    	int val2;
    	float val3;
    	double val4;
    };
    
    int main()
    {
    myStruct *s = new myStruct[5];
    s[0].val1 = true;//works, but does not call the overloaded operator
    s->operator[](0).val1 = 1;//calls the overloaded operator - also works
    
    ...
    }
    I can't find anything on the Internet or any textbooks about this. Any clues as to why this doesn't work would be appreciated.

    Thanks, Greg
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    #2
    Originally posted by gvr123
    Hi all

    This seems to me a peculiar problem, but confounding nonetheless...

    The problem seems to be that an overloaded subscript operator isn't being called unless it is called explicitly

    Code:
    struct myStruct
    {
    	myStruct& operator[] (int index)
    	{	
    		return *(this + index);
    	}
    
    	bool val1;
    	int val2;
    	float val3;
    	double val4;
    };
    
    int main()
    {
    myStruct *s = new myStruct[5];
    s[0].val1 = true;//works, but does not call the overloaded operator
    s->operator[](0).val1 = 1;//calls the overloaded operator - also works
    
    ...
    }
    I can't find anything on the Internet or any textbooks about this. Any clues as to why this doesn't work would be appreciated.

    Thanks, Greg
    I'm not completely sure about this, but allow me to give you an educated guess:

    In your first example s[0].val1 = true; you are using the subscript operator on the pointer. This will return the first myStruct in the array - you can then access val1 correctly. However, the subscript operator is called on the pointer, not the struct.

    In your second example s->operator[](0).val1 = 1; the -> is evaluated on the pointer first, giving you the myStruct at s (Since s is a pointer to an array, it will return the first element of the array). Then you call the subscript function explicitly.

    You may be able to use the overloaded function like this:

    Code:
    myStruct *s = new myStruct[5];
    s[0][0].val1 = true;
    As an aside, what are you trying to accomplish by overloading the [] operator? It looks like you are treating the object as an array, but it will actually give you the address in memory index slots in front of the object, which will be pointing to random, garbage memory.

    Comment

    • JosAH
      Recognized Expert MVP
      • Mar 2007
      • 11453

      #3
      You defined an overloaded operator on a type T, not on a type T* (which is
      impossible btw). Doing a *(this+index) is extremely dangerous because it
      assumes that all your type Ts are stored consecutively in memory; and that's
      not what the operator[](int) is supposed to do when overloaded, i.e. the non-
      overloaded version can do that too; it doesn't need overloading for that.

      kind regards,

      Jos

      Comment

      • gvr123
        New Member
        • Apr 2007
        • 6

        #4
        Originally posted by Ganon11
        I'm not completely sure about this, but allow me to give you an educated guess:

        In your first example s[0].val1 = true; you are using the subscript operator on the pointer. This will return the first myStruct in the array - you can then access val1 correctly. However, the subscript operator is called on the pointer, not the struct.

        In your second example s->operator[](0).val1 = 1; the -> is evaluated on the pointer first, giving you the myStruct at s (Since s is a pointer to an array, it will return the first element of the array). Then you call the subscript function explicitly.

        You may be able to use the overloaded function like this:

        Code:
        myStruct *s = new myStruct[5];
        s[0][0].val1 = true;
        As an aside, what are you trying to accomplish by overloading the [] operator? It looks like you are treating the object as an array, but it will actually give you the address in memory index slots in front of the object, which will be pointing to random, garbage memory.
        Hi

        Here's a more compete example of what I'm trying to do:

        Effectively I'm trying to implement some bounds checking on the array. I wanted to leave the pointer to the array of Struct2 public (for various reasons) but still wanted to provide some additional safety. (The pointer is const in the actual implementation)

        Code:
        struct myStruct2
        {
        	myStruct2() { memset((void*)this, 0, sizeof(myStruct2)); }
        	~myStruct2(){}
        	myStruct2& operator[] (int index)
        	{	
        		return *(this + index);//increment this by index
        	}
        
        	bool val1;
        	int val2;
        	float val3;
        	double val4;
        };
        
        struct myStruct
        {
        	myStruct() : number(0), pStruct(NULL)
        	{
        	}
        
        	~myStruct()
        	{
        		if(pStruct) delete [] pStruct;
        		pStruct = NULL;
        	}
        
        	void alloc(int num)
        	{
        		pStruct = new myStruct2[num];
        		if(pStruct) number = num;
        		else number = 0;
        	}
        
        	int number;
        	myStruct2* pStruct;
        };
         
        int main()
        {
        	myStruct s;
        
        	s.alloc(5);
        
        	s.pStruct[4].val1 = true;
        	s.pStruct[4].val2 = 1;
        	s.pStruct[4].val3 = 2.2F;
        	s.pStruct[4].val4 = 3.33;
        
        	myStruct2 s3 = s.pStruct[4];
        
        	myStruct2 s4 = s.pStruct->operator [](4);
        
        
        	return 0;
        }
        The deferencing seems to work fine - s3 and s4 are identical - but I get what you mean by operating on the struct rather than the pointer.

        So what i really want to know is is it possible to force the array subscript to use the struct operator[]?

        Thanks

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          Originally posted by gvr123
          Hi
          So what i really want to know is is it possible to force the array subscript to use the struct operator[]?

          Thanks
          You basically want to do the same as a vector<T>; the vector takes care of the
          overloaded operator[] which is the only way to do it because you can't overload
          anything on a primitive type such as a pointer to T (or an array of T).

          kind regards,

          Jos

          Comment

          Working...