How to use class forward declaration?

 

I am trying to build a 1d array that can take in 2d array as index and return another 2d array with the contend of 1d array:

C1dArray<int> labels = {10,11};
C2dArray<int> index = {{0,1,1,0},{1,0,0,1}};
labels[index] will return {{10,11,11,10},{11,10,10,11}}

3 sample files are attached that will implement this functionality.  However, in the design, class C2dArray contains an array of class C1dArray. 

So class C1dArray has to be declared before class C2dArray.  But then C1dArray operator [] method also takes in C2dArray to return C2dArray, example below:

class C1dArray
{
...
};

class C2dArray
{
C1dArray m_rows[];
};

class C1dArray
{
public:
     C2dArray operator[](C2dArray index) { ...}
};

Obviously compiler will complain the C1dArray identifier is already used, so I have to circumvent this problem by using another class to support the functionality I want:

class C1dArray
{
...
};

class C2dArray
{
C1dArray m_rows[];
};

class C1dArraySlice:public C1dArray
{
public:
     C2dArray operator[](C2dArray index) { ...}
};

In this way, I can now use C1dArraySlice to do the fancy indexing I need.  However, I wanted this functionality to be in class C1dArray instead of arbitrary create another class C1dArraySlice because in class C2dArray, I have a lot of methods that will return C1dArray that have this functionality too!

Can someone enlighten me how to use forward declaration in MQL4 to solve this problem?

 
williamwong:

Can someone enlighten me how to use forward declaration in MQL4 to solve this problem?

It's almost certainly much simpler than you think it is:

// Forward declarations...
class C1dArray;
class C2dArray;


// Actual definitions of classes (in either order)...
class C2dArray
{
C1dArray m_rows[];
};

class C1dArray
{
public:
     C2dArray operator[](C2dArray index) { ...}
};
 
JC:

It's almost certainly much simpler than you think it is:

Thanks for the tip.  I changed the codes, but got "'m_rows' - default constructor of class 'C1dArray<int>' is not defined 2darray q on forward declaration.mqh 17 15" compilation error.

I am not sure what is the problem.

 
williamwong:

I am not sure what is the problem.

The problem is this block of code inside C1dArray.

C2dArray<T>operator[](C2dArray<int>&index)
     {
      C2dArray<T>ans;
      for(int row=0;row<index.size();row++)
        {
         C1dArray<int>r=index[row];
         C1dArray<T>v=operator[](r);
         ans.append(v);
        }
      return ans;
     }

I don't immediately see an actual problem with this. It's possible that you've hit a limit of the MQL compiler here...

 
JC:

The problem is this block of code inside C1dArray.

I don't immediately see an actual problem with this. It's possible that you've hit a limit of the MQL compiler here...


I have raised this bug to the service desk.  Hopefully it will be resolved in the next version.  Thanks anyway.
 

Your code from the initial post compiles and runs without a problem if you correct filenames in the include directives (you have blanks instead of underscores).

2017.10.12 16:28:33.490 mt_Test_q_on_forward_declaration (EURUSD,M1)    [0] {0,1,1,0}
2017.10.12 16:28:33.490 mt_Test_q_on_forward_declaration (EURUSD,M1)    [1] {1,0,0,1}
2017.10.12 16:28:33.490 mt_Test_q_on_forward_declaration (EURUSD,M1)    [0] {10,11,11,10}
2017.10.12 16:28:33.490 mt_Test_q_on_forward_declaration (EURUSD,M1)    [1] {11,10,10,11}
 
Stanislav Korotky:
Your code compiles without a problem if you correct filenames in the include directives (you have blanks instead of underscores).

Have you tried instantiating the C1dArray class?

The code compiles by itself, but I get the same error as the OP if I then add the following:

void OnStart()
{
   C1dArray<int> test;
}
(Note: using the OP's revised code, not the originally posted code)
 
JC:

Have you tried instantiating the C1dArray class?

.. The following does compile:

void OnStart()
{
   C2dArray<int> test2d;
   C1dArray<int> test1d;
}

But it fails if you comment-out the first line. Something must be wrong, because these things should be independent.

void OnStart()
{
   // C2dArray<int> test2d;
   C1dArray<int> test1d;
}
 
JC:

.. The following does compile:

But it fails if you comment-out the first line. Something must be wrong, because these things should be independent.


It works for me in both cases.

 
Stanislav Korotky:

It works for me in both cases.

It works for me using the OP's original code. But not the revised code. The problem seems to be related to additions since the original code, as identified above, where C2dArray contains a reference to C1dArray and also C1dArray contains a reference to C2dArray.

(The OP's original question was about forward declarations. The original code doesn't require them. The issue, and this thread, is around the additions to the original code which the OP wants to make.)

 
JC:

It works for me using the OP's original code. But not the revised code. The problem seems to be related to additions since the original code, as identified above, where C2dArray contains a reference to C1dArray and also C1dArray contains a reference to C2dArray.

(The OP's original question was about forward declarations. The original code doesn't require them. The issue, and this thread, is around the additions to the original code which the OP wants to make.)


Can you post actual codes to check?

As for "default constructor" error, you should either define it in order to declare array of objects m_rows[], or change its type to array of pointers and create/copy instances as appropriate.

Reason: