Ponteiro de Objeto de classe template

 

Boa noite. Há possibilidade de obter o ponteiro de um objeto de classe template sem saber o tipo real aplicado ao objeto. Estou tentando algo nesse sentido, mas o compilador diz que a função já está definida com um tipo diferente.


#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
class CInput:public CObject
  {
private:
   T                 m_value;
   string            m_label;
   string            m_name;
public:
                     CInput(void);
                    ~CInput(void);
   
   T                 Value(void)                                     {return m_value;}
   void              Value(const T value)                            {m_value=value;}
   
   string            Name(void)                                      {return m_name;}
   void              Name(const string value)                        {m_name=value;}
   
   string            Label(void)                                     {return m_label;}
   void              Label(const string value)                       {m_label=value;}
   
   string            Type(void)                                      {return typename(m_value);}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
CInput::CInput(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
CInput::~CInput(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class COperator
  {
private:
   CArrayObj         m_arr;
public:
                     COperator(void);
                    ~COperator(void);
   
   template<typename T>
   bool              InputAdd(const string name, const T default_value, const string label=NULL);
   
   template<typename T>
   CInput<T>*        Input(const int index)                          ;
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COperator::COperator(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COperator::~COperator(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
bool COperator::InputAdd(const string name,const T default_value,const string label=NULL)
  {
   for(int i=0;i<m_arr.Total();i++)
     {
      CInput<T>* pointer = m_arr.At(i);
      if(CheckPointer(pointer)==POINTER_INVALID)
        {
         continue;
        }
      if(pointer.Name()==name)
        {
         Print("identifier already used!");
         return false;
        }
     }
   CInput<T>* pointer = new CInput<T>;
   m_arr.Add(pointer);
   pointer.Name(name);
   pointer.Label(label==NULL?name:label);
   pointer.Value(default_value);
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
CInput<T>* COperator::Input(const int index)
  {
   if(index<0||index>=m_arr.Total())
     {
      return NULL;
     }
   return m_arr.At(index);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Documentação sobre MQL5: Elementos Básicos da Linguagem / Tipos de Dados / Estruturas, Classes e Interfaces
Documentação sobre MQL5: Elementos Básicos da Linguagem / Tipos de Dados / Estruturas, Classes e Interfaces
  • www.mql5.com
Estruturas, Classes e Interfaces - Tipos de Dados - Elementos Básicos da Linguagem - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 
Samuel Manoel De Souza:

Boa noite. Há possibilidade de obter o ponteiro de um objeto de classe template sem saber o tipo real aplicado ao objeto. Estou tentando algo nesse sentido, mas o compilador diz que a função já está definida com um tipo diferente.

O que é esse Objeto CInput ?

Pode dar mais detalhes do código? pois a mineira que está me parece estranho e com certeza irá dar erro, eu não entendi o contexto na real!

 
Jonathan Pereira #:

O que é esse Objeto CInput ?

Pode dar mais detalhes do código? pois a mineira que está me parece estranho e com certeza irá dar erro, eu não entendi o contexto na real!

Tome como exemplo as janelas de inputs de indicadores, scripts e EAs. Declaramos as variáveis de entrada, automaticamente o compilador cria as janelas com os controles de acordo com o tipo do parâmetro, int, double, datetime, etc...

A ideia é criar uma lista com tipos de dados quaisquer, para posterior manipulação.

Editei o código acima. Dê uma olhada novamente.

 
Se eu alterar o retorno para 
CInput*

não dá erro com relação a isso, mas há outro problema com relação a variável que vai receber o ponteiro, pelo fator de não saber o tipo e o CInput tem que ser declarado no formato CInput<tipo>* nome_da_variavel

 

Acho que isso vai servir, mas se tiver outra sugestão gostaria de saber.

#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CInput:public CObject
  {
private:
   string            m_type;
   string            m_label;
   string            m_name;
   string            m_value;
public:
                     CInput(void);
                    ~CInput(void);
   
   string            Value(void)                                     {return m_value;}
   void              Value(const string value)                       {m_value=value;}
   
   string            Type(void)                                      {return m_type;}
   void              Type(const string value)                        {m_type=value;}
   
   string            Name(void)                                      {return m_name;}
   void              Name(const string value)                        {m_name=value;}
   
   string            Label(void)                                     {return m_label;}
   void              Label(const string value)                       {m_label=value;}
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CInput::CInput(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CInput::~CInput(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class COperator
  {
private:
   CArrayObj         m_arr;
public:
                     COperator(void);
                    ~COperator(void);
   
   template<typename T>
   bool              InputAdd(const string name, const T default_value, const string label=NULL);
   
   string            Value(const int index)                          ;
   string            Type(const int index)                           ;
   int               Total(void)                                     {return m_arr.Total();}
   
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COperator::COperator(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COperator::~COperator(void)
  {
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename T>
bool COperator::InputAdd(const string name,const T default_value,const string label=NULL)
  {
   for(int i=0;i<m_arr.Total();i++)
     {
      CInput* pointer = m_arr.At(i);
      if(CheckPointer(pointer)==POINTER_INVALID)
        {
         continue;
        }
      if(pointer.Name()==name)
        {
         Print("identifier already used!");
         return false;
        }
     }
   CInput* pointer = new CInput;
   m_arr.Add(pointer);
   pointer.Name(name);
   pointer.Label(label==NULL?name:label);
   pointer.Value(default_value);
   pointer.Type(typename(default_value));
   return true;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string COperator::Value(const int index)
  {
   if(index<0||index>=m_arr.Total())
     {
      return NULL;
     }
   CInput* pointer = m_arr.At(index);
   return pointer.Value();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string COperator::Type(const int index)
  {
   if(index<0||index>=m_arr.Total())
     {
      return NULL;
     }
   CInput* pointer = m_arr.At(index);
   return pointer.Type();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
COperator teste;

enum enum_sim_nao
  {
   sim,
   nao
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   teste.InputAdd("name_d",0.0,"Teste");
   teste.InputAdd("name_s","string","Teste");
   teste.InputAdd("name_i",0,"Teste");
   teste.InputAdd("name_t",TimeCurrent(),"Teste");
   teste.InputAdd("name_c",clrRed,"Teste");
   teste.InputAdd("name_e",sim,"Teste");
   
   for(int i=0;i<teste.Total();i++)
     {
      Print("type: ",teste.Type(i),", value: ",teste.Value(i));
     }
//---
   return(INIT_SUCCEEDED);
  }