Template function typification with objects and object pointers

 

I am trying to typify a template function with an object pointer like you can see below. But I always get "invalid pointer access".

//+------------------------------------------------------------------+
//| Class Foo                                                        |
//+------------------------------------------------------------------+
class CFoo
{
public:

   string A;
   double B;
   double C;
};
//+------------------------------------------------------------------+
//| Class Bar                                                        |
//+------------------------------------------------------------------+
class CBar
{
public:

   template<typename T>
   T   Func(const string in);
}Bar;
//+------------------------------------------------------------------+
//| Func                                                             |
//+------------------------------------------------------------------+
template<typename T>
T CBar::Func(const string in)
{
   // T = type of object pointer (e.g. CFoo*) 
   T obj;
   
   // Do something with object like access members etc.
   obj.A = in;
   obj.B = 1.0;
   obj.C = 2.0;

   return(obj);
}
//+------------------------------------------------------------------+
CFoo *foo = Bar.Func<CFoo*>("foo");
//+------------------------------------------------------------------+

Is this possible in mql? If so, what do I have to change to make it work? Thank you for your help! :)

 
Domp:

I am trying to typify a template function with an object pointer like you can see below. But I always get "invalid pointer access".

Is this possible in mql? If so, what do I have to change to make it work? Thank you for your help! :)

You need to instantiate your pointer.

class CBar
{
public:

   template<typename T>
   T* Func(const string in);
}Bar;

template<typename T>
T* CBar::Func(const string in)
{
   // T = type of object pointer (e.g. CFoo*) 
   T* obj=new T;
   
   // Do something with object like access members etc.
   obj.A = in;
   obj.B = 1.0;
   obj.C = 2.0;

   return(obj);
}
void OnStart()
  {
//---
   CFoo *foo = Bar.Func<CFoo>("foo");
  }
 
Alain Verleyen:

You need to instantiate your pointer.

This is better form since you are in fact returning a pointer to an object and not a copy, just like in c++ you would declare a vector of pointers as vector<Obj*> vect;


class CBar
{
public:

   template<typename T>
   T* Func(const string in);
}Bar;

template<typename T>
T CBar::Func(const string in)
{
   // T = type of object pointer (e.g. CFoo*) 
   T obj=new T;
   
   // Do something with object like access members etc.
   obj.A = in;
   obj.B = 1.0;
   obj.C = 2.0;

   return(obj);
}
void OnStart()
  {
//---
   CFoo *foo = Bar.Func<CFoo*>("foo");
  }
However, this is a really bad practical example since T can never be anything other than a CFoo* object. There's no point to the template in this particular example... 
 
nicholishen:

This is better form since you are in fact returning a pointer to an object and not a copy, just like in c++ you would declare a vector of pointers as vector<Obj*> vect;

Excepted your code doesn't compile.

 
Alain Verleyen:

Excepted your code doesn't compile.

I didn't test it, but the reason is pretty obvious... can you figure out why it won't compile? Hint: It's an obvious typo ;)

 
nicholishen:

I didn't test it, but the reason is pretty obvious... can you figure out why it won't compile? Hint: It's an obvious typo ;)

I am not talking about the typo, but about "new T", which resolved to "new CFoo*".

That's why I changed to OP code, to provide a working solution.

 
Alain Verleyen:

I am not talking about the typo, but about "new T", which resolved to "new CFoo*".

That's why I changed to OP code, to provide a working solution.

It still would never apply in a real-world programming scenario. In order for it to do anything you be (dangerously) calling upon the A,B,and C attributes of T object, and if they are not defined within T object then you get a fatal error. That's why I mentioned that this a terrible design pattern and should never be used outside of just learning how functions can return pointers. If this specific example is what's needed then this design pattern should implement a polymorphic schema instead of templating. 

 
nicholishen:

It still would never apply in a real-world programming scenario. In order for it to do anything you be (dangerously) calling upon the A,B,and C attributes of T object, and if they are not defined within T object then you get a fatal error. That's why I mentioned that this a terrible design pattern and should never be used outside of just learning how functions can return pointers. If this specific example is what's needed then this design pattern should implement a polymorphic schema instead of templating. 

I just answered the OP question without working code. I never supposed a code code with Bar/Foo classes is a real-world programming scenario.

Of course your remarks are correct.

 
nicholishen:

This is better form since you are in fact returning a pointer to an object and not a copy, just like in c++ you would declare a vector of pointers as vector<Obj*> vect;

Well, for learning purpose I wanted to understand your code. I've tried to fix the code but without success. I suppose the typo is the pointer in Func declaration but still the code doesn't compile. Could someone, please, show me the fix?
class CBar
{
public:

   template<typename T>
   T Func(const string in);
}Bar;

template<typename T>
T CBar::Func(const string in)
{
   // T = type of object pointer (e.g. CFoo*) 
   T obj=new T;
   
   // Do something with object like access members etc.
   obj.A = in;
   obj.B = 1.0;
   obj.C = 2.0;

   return(obj);
}
void OnStart()
  {
//---
   CFoo *foo = Bar.Func<CFoo*>("foo");
  }
 
Petr Nosek:
Well, for learning purpose I wanted to understand your code. I've tried to fix the code but without success. I suppose the typo is the pointer in Func declaration but still the code doesn't compile. Could someone, please, show me the fix?

It can't compile as the template is called with a pointer, the only fix is to change the approach, see my post above.

 CFoo *foo = Bar.Func<CFoo*>("foo");

But the following code can't compile :

 T obj=new T;

become

 CFoo* obj=new CFoo*;
 
Alain Verleyen:

It can't compile as the template is called with a pointer, the only fix is to change the approach, see my post above.

Your approach is clear to me. But I wanted to learn something new.

Alain Verleyen:
 

But the following code can't compile :

I've tried this:

T obj=new CFoo;

but without success.

Reason: