Errores, fallos, preguntas - página 2657

 
Stanislav Korotky:

Esa es la cuestión, el árbol de clases tiene un nodo común CWnd (CObject está más lejos, generalmente en la raíz).

CButton -> CWndObj -> CWnd -> CObject.

Si cambias el parámetro en el método a CObject, obtienes 2 veces más errores:

Una jerarquía de clases similar funciona para el caso de las no matrices. Aquí está el código compilado:

La cuestión es cómo hacer que funcione también para una matriz.

Sé que una plantilla ayuda, pero quiero evitarlo.

En mi opinión, debería funcionar sin plantillas por derecho de herencia.

Lo he comprobado como en C++.

Funciona. Pero MQL no lo digiere, tanto con el índice como sin él.

Para C++, su ejemplo sería mucho más claro. Sólo tienes que ejecutarlo y ver qué pasa)))

class CWnd
{
public:
    int x;
    CWnd(int _x = 10) : x(_x) {}
};
class CButton : public CWnd
{
    int a;
public:
    CButton(int _a=6) : CWnd(),a(_a) {}
};

class Collection
{
public:
    Collection(CWnd* ptr,size_t size) {
        for (int i = 0; i < size; cout << ptr[i++].x<<endl);
    }
};

int main()
{
    CButton buttons[10];
    CWnd wnd[10];
    Collection data1(&wnd[0],_countof(wnd));
    cout << "------------------------------" << endl;
    Collection data2(&buttons[0],_countof(buttons));
    return 0;
}
 

Sí, culpa mía. Pero entonces surge la siguiente pregunta. Este código C++ funciona (ya exactamente bien ;-)).

class Base
{
  public:
    virtual void method1(void) { cout << "2\n"; }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { cout << "3\n"; }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr->T::method1();
    }
};

int main()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // ok

  return 0;
}

Un MQL similar da error:

class Base
{
  public:
    virtual void method1(void) { Print(__FUNCSIG__); }
};

class Derived: public Base
{
  public:
    virtual void method1(void) override { Print(__FUNCSIG__); }
};

template<typename T>
class Wrapper
{
  public:
    Wrapper(T *ptr)
    {
      ptr.T::method1(); // <<< 'Base' is not a class, struct or union
    }
};


void OnStart()
{
  Derived d;
  d.Base::method1();   // ok
  Wrapper<Base> w(&d); // causes the error above
 
Stanislav Korotky:

Sí, culpa mía. Pero entonces surge la siguiente pregunta. Este código C++ funciona (ya exactamente bien ;-)).

Un MQL similar da un error:

No conozco la tarea, pero creo que buscas algo así:

typedef void(*PTR)(void);

en MQL es un puntero a una función void func(void)

en una clase, puede declarar un campo de tipo PTR y luego asignarle una función, y luego "desreferenciar el puntero" y llamar a la función

pasar funciones escritas en estilo procedimental a la clase funciona sin problemas, los métodos de la clase probablemente no se pueden pasar tan fácilmente, puedes intentar usar dynamic_cast, pero el código se volverá muy confuso

 
Igor Makanu:

No conozco la tarea, pero creo que está buscando algo así:

en MQL es un puntero a una función void func(void)

en una clase, puedes declarar un campo de tipo PTR y luego asignarle una función y luego "desreferenciar el puntero" y llamar a la función

pasar funciones escritas en estilo procedimental a la clase funciona sin problemas, los métodos de la clase probablemente no se pueden pasar tan fácilmente, puedes intentar usar dynamic_cast, pero el código se volverá muy confuso

typedef no funcionará con un método.

dynamic_cast funciona hacia el heredero (cadena más larga), es decir, si el puntero a la base contiene al derivado, entonces se puede hacer el casting al derivado y si no es NULL (es decir, el cast normal), llamar a su método. Pero cuando la situación es contraria, como en mi caso, hay puntero a derivado entonces es por definición también base. Y cualquier invocación de su método virtual descubre que el derivado está "sentado" en el puntero y llama a la implementación anulada. Se necesita la base.

Existe la construcción de sintaxis mencionada en C++ para este propósito, pero MQL no es C++. Al parecer, aún no hay forma de hacerlo.

Hice una solución pero puede que no funcione bien en todas las tareas.

El objetivo de todo este baile de pandereta, como siempre, es mantener el código enredado dentro de la "biblioteca" y hacer que el código que lo utiliza sea claro y sencillo.

 

¿con qué inicializar rand() en el probador?

código:

input ulong param = 18446744073709551615;
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      srand(GetTickCount()); 
      return(rand());
   }
//+------------------------------------------------------------------+

No me gusta mucho este tipo de generación pseudo-aleatoria:


 
Igor Makanu:

¿con qué inicializar rand() en el probador?

código:

No me gusta mucho este tipo de generación pseudo-aleatoria:


Ayuda:MathRand

Nota

Antes de llamar a la función por primera vez, es necesario utilizarMathSrand para poner el generador de números pseudoaleatorios en el estado inicial.


Pruébalo ahora con MathSrand.

Документация по MQL5: Математические функции / MathRand
Документация по MQL5: Математические функции / MathRand
  • www.mql5.com
Математические функции / MathRand - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Karputov:

Referencia:MathRand

Nota

La funciónMathSrand debe utilizarse antes de la primera llamada a la función para poner el generador de números pseudoaleatorios en el estado inicial.

¡Gracias Cap!

Estamos hablando del probador.

este código tampoco funciona en el probador

input ulong param = 18446744073709551615;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
   {
   MathSrand(GetTickCount()); 
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

Creo que, si un probador, no hay necesidad de utilizar MathSrand.

Pero si eso no ayuda, lo más probable es que el probador esté forzando MathSrand(GetTickCount()) en algún momento.

Entonces prueba MathSrand(int(GetMicrosecondCount()%1000000));

Recuerde que GetTickCount() cambia su valor cada 15,625 milisegundos. Es un intervalo de tiempo muy largo para un probador.

 
Nikolai Semko:

Creo que, si un probador, no hay necesidad de utilizar MathSrand.

esto contradice la documentaciónhttps://www.mql5.com/ru/docs/math/mathrand

Antes de la primera llamada a la función, es necesario utilizar la función MathSrand para poner el generador de números pseudoaleatorios en su estado inicial.

No quiero revisar el código fuente, pero para los paquetes de redes neuronales la inicialización por valor aleatorio de los pesos NS es obligatoria, sospecho que esto se hizo de acuerdo con el material de ayuda de MQL - es decir, se utilizó srand()

Es decir, el uso de programas MQL dentro del probador con dicho paquete NS tendrá lugar muy probablemente en un núcleo de procesador - los pesos iniciales NS tendrán los mismos valores, ¿verdad?

es aún más genial sin srand()

int OnInit()
   {
   return(INIT_SUCCEEDED);
   }
//+------------------------------------------------------------------+
void OnTick()
   {
   }
//+------------------------------------------------------------------+
double OnTester()
   {
      return(rand());
   }
//+------------------------------------------------------------------+
 
Igor Makanu:

esto contradice la documentaciónhttps://www.mql5.com/ru/docs/math/mathrand

No quiero buscar en el código fuente, pero para los paquetes de redes neuronales la inicialización por valor aleatorio de los pesos NS es obligatoria, sospecho que esto se hizo de acuerdo con el material de ayuda de MQL - es decir, se utilizó srand()

Es decir, el uso de programas MQL dentro del probador con dicho paquete NS tendrá lugar muy probablemente en un núcleo de procesador - los pesos iniciales NS tendrán los mismos valores, ¿verdad?

aún más divertido sin srand()

Igor, entonces prueba con MathSrand(int(GetMicrosecondCount()%16384));

Me pregunto cómo cambiará la imagen.

Razón de la queja: