Forward declaration is not working

 

Hi,

I have used forward declaration before, but for some reason this situation fails. Any idea what I'm doing wrong?

I have attached the necessary files also.



#include<Test\Foo.mqh>
#include<Test\FooNode.mqh>

Foo<FooNode*> foo;

int OnInit()
  {
   return (INIT_SUCCEEDED);
  }

void OnTick()
  {
   foo = new Foo<FooNode*>();
  }
class Bar;

#include<Generic\LinkedList.mqh>
#include<Test\Bar.mqh>

template<typename T>
class Foo: public CLinkedList<T>
  {

public:
                     Foo(): CLinkedList<T>()
     {

     }

public:
   void              test()
     {
      Bar *bar = new Bar(GetPointer(this));
     }
  };

class FooNode
  {

   
public:
                     FooNode()
     {

     }
  };


class FooNode;
template <typename T> class Foo;

#include<Test\Foo.mqh>
#include<Test\FooNode.mqh>

class Bar
  {

public:
                     Bar(Foo<FooNode*> *foo)
     {
     
     }
  };
Files:
Foo.mqh  1 kb
FooNode.mqh  1 kb
Test.mq5  2 kb
Bar.mqh  1 kb
 
I debugged further and learned that I need to forward declare generics like this
template <typename T> class Foo;

Tho, still one error remains.

Have updated the main post.

 
lastpunisher #:
I debugged further and learned that I need to forward declare generics like this

Tho, still one error remains.

Have updated the main post.

It's not clear why you need forward declaration at all with your simplified code.

#include<Generic\LinkedList.mqh>

template<typename T>
class Foo: public CLinkedList<T>
  {
public:
                     Foo(): CLinkedList<T>()
     {
     }

public:
   void              test()
     {
      Bar *bar = new Bar(GetPointer(this));
     }
  };
#include<Test\Foo.mqh>
#include<Test\FooNode.mqh>

class Bar
  {
public:
                     Bar(Foo<FooNode*> *foo)
     {     
     }
  };
#include<Test\Bar.mqh>

Foo<FooNode*> *FOO;

int OnInit()
  {
   return (INIT_SUCCEEDED);
  }

void OnTick()
  {
   FOO = new Foo<FooNode*>();
  }
 
Alain Verleyen #:

It's not clear why you need forward declaration at all with your simplified code.

I have developed a module based event listener framework to handle the complexity of the strategy. Until now I have not had to forward declare a generic variable.

This is simplified, to illustrate the problem, once the problem gets solved I will apply the solution on my framework. As the illustration is an identical structure to my code.

I have searched a solution in C++ related topics and what I have now is what I have found out, but still I'm stuck as I can't spot the mistake.

Although, I have plenty of experience in software development in other language, I have still hit a wall with this issue in C++ :).

 
lastpunisher #:

I have developed a module based event listener framework to handle the complexity of the strategy. Until now I have not had to forward declare a generic variable.

This is simplified, to illustrate the problem, once the problem gets solved I will apply the solution on my framework. As the illustration is an identical structure to my code.

It's not identical as I solved it without forward declaration, as demonstrated in my previous post.

 
Alain Verleyen #:

It's not identical as I solved it without forward declaration, as demonstrated in my previous post.

Odd, can't solve my issue and the original solution is too big to post. I will look into it and will try to make a more adequate example.

Thank you for help tho.

 
I would suggest to redesign your code.
Forward declarations are even in C++ a pain. And Mql is by far less developed.

I also built an event handler (pub, sub) but using a typedef of a callback method.
So I can have an array of the callback method pointers and execute all of them.
Works only on callback methods coming from the global mq5 file tho - Mql does not support pointers to callback methods inside objects (instantiated classes).

Since you are playing around with classes, define a parent class with a method onEvent(...)
and register all subscribed classes as pointers in an array. If the event occurs, do something like
For each class pointer call pointer.onEvent(...)

Good luck
 

I went into this problem, too and maybe I found a solution or at least can tell where the problem is.

I guess the compilation fails when you try to compile the file where the forward-declared class is declared (Foo).
But this should be no problem, if you include the Foo-class with it's forward-declaration in another file and use it.
So it would only be an issue if you declare the forward-declaration in the EA-file itself because this is the only file you
have to compile.

Forward-declaration is completely legit because there are cases where the code gets much more complex if you work around it.

I hope this helps anyone.

 

And I found another, more "elegant" solution on stackoverflow:

Just include the file of the forward-declared class at the bottom of the file where the forward-declaration is. Now you can even compile the file Foo.
Still not perfect but I guess there is no better solution.

By the way, I just tested the test-code above and found no issue compiling it.
But my code is a bit different. I have a class A that includes class B and class B includes class C and class C works with methods from class A.
So I used forward-declaration to break the include-cycle.

Reason: