Custom indexing of an array / subscript operation overloading

To add comments, please log in or register
rgne
17
rgne  

Hey guys,

I am getting acquainted with the mql language, but I have some knowledge of C++.

I want a data structure where I can link a value to another. I was thinking of a map- (C++) or dictionary- (Python) like structure, but it is an overkill for my purposes. So I was thinking of a custom array type, where the subscript is assigned by the program (e.g.: the index will not be 0, 1, 2, 3, but 2, 10, 3, 900, and the length of the array will still be 4, and I can assigne values to these indices, like: list[900] = 2;).  It  can be done with operator overloading in C++, but I can't seem to get it work in mql. The official document is not much help.

Here is the  class:

class cArray
{
private:
        int m_list[10];
public:
        int operator[] (const int index) const
        {
                   return (m_list[index]);
        }; 
};


and here is a simple use:

   cArray list; 
   int index = 2;
   list[index] = 3;
   Print(list[index]);


But since I can't overload the [] operator by reference, like:

int& operator[] (const int index) const...

it complains that in

list[index] = 3;

l-value is required.


So my question is: how can I (can I even) overload the subscript operator for the above snipet to work?


Thanks in advance.
Anthony Garot
1842
Anthony Garot  

This is MQL4, but it may give you some direction for your issue with the l-value.

https://www.mql5.com/en/blogs/post/680572

MQL's OOP notes: Arrayed indicator buffers based on operators overloading
MQL's OOP notes: Arrayed indicator buffers based on operators overloading
  • 2016.09.16
  • Stanislav Korotky
  • www.mql5.com
From very first moment as I started learning MetaTrader many years ago I was wondering why there are no multidimentional buffers in indicators. Indeed, when you code an indicator with multiple buffers you need to declare them one by one: This would not only spare a couple of lines, but allow streamline further calculations tremendously...
rgne
17
rgne  
Anthony Garot:

This is MQL4, but it may give you some direction for your issue with the l-value.

https://www.mql5.com/en/blogs/post/680572

Thanks Anthony, I'll have a look.
nicholi shen
1884
nicholi shen  
rgne:

I want a data structure where I can link a value to another. 

You can't do assignment like that since you're returning an int, which is the equivalent to 5 = 7;

In order to implement assignment in the way you're attempting you'll need to return a reference to an object whose assignment operator has also been overloaded.  ...which might look something like this. 


#include <Arrays\List.mqh>

class IntWrapper : public CObject
{
public:
   int custom_index;
   int num;
   void operator = (int n) { num = n; }
};

class MyIntList : public CList
{
public:
   IntWrapper *operator[](int i)
   {
      IntWrapper *iw = this.GetFirstNode();
      for(; CheckPointer(iw); iw=iw.Next())
         if(iw.custom_index == i)
            return iw;
      iw = new IntWrapper();
      this.Add(iw);
      iw.custom_index = i;
      return iw;
   }
};


void OnStart()
{
   MyIntList list;
   
   list[900] = 25;
   list[5] = 1900;
   
   Print(list[900].num);

}
rgne
17
rgne  
nicholi shen:

You can't do assignment like that since you're returning an int, which is the equivalent to 5 = 7;

In order to implement assignment in the way you're attempting you'll need to return a reference to an object whose assignment operator has also been overloaded.  ...which might look something like this. 


Hey Nicholi, yes, exactly! I was thinking the same, but I hoped there was a simpler way to do it.

Thanks for the code, I will go through it. Really appreciate the help.

rgne
17
rgne  
nicholi shen:

You can't do assignment like that since you're returning an int, which is the equivalent to 5 = 7;

In order to implement assignment in the way you're attempting you'll need to return a reference to an object whose assignment operator has also been overloaded.  ...which might look something like this. 


Hey Nicholi,

just a quick question. Do I understand correctly that you basically created a linked list, and use that to add elements? So the lookup of a value wouldn't be O(1), but O(n)? If not, just let me know and I'll go back studying your code.

Thanks again.

Robert

nicholi shen
1884
nicholi shen  
rgne:

Hey Nicholi,

just a quick question. Do I understand correctly that you basically created a linked list, and use that to add elements? So the lookup of a value wouldn't be O(1), but O(n)? If not, just let me know and I'll go back studying your code.

Thanks again.

Robert

Correct, and typically I would use CArrayObj for this use since it is faster than a linked list -- a linked list is just easier to demonstrate. Also, you said you had four elements so O(n) in this case is still faster than running a hashing algo plus lookup. If you have a large data collection and need key: value pairs then obviously you'd need a hash-map (dictionary). 

rgne
17
rgne  
nicholi shen:

Correct, and typically I would use CArrayObj for this use since it is faster than a linked list -- a linked list is just easier to demonstrate. Also, you said you had four elements so O(n) in this case is still faster than running a hashing algo plus lookup. If you have a large data collection and need key: value pairs then obviously you'd need a hash-map (dictionary). 

Got it, thanks.
To add comments, please log in or register