Errores, fallos, preguntas - página 2661

 
Nikolai Semko:

Pido disculpas por haber simplificado el código al mínimo, introduciendo con ello ciertas inexactitudes, en particular:
- los objetos pasados a la función tienen el mismo tamaño (código actualizado);
- en lugar de la salida tonta printf("1");/printf("2"); en realidad se accede directamente a la interfaz o a los internos del objeto, lo que a su vez no permite inlinear dos algoritmos en una sola función de llamada (código actualizado).

 
Sergey Dzyublik:

Pido disculpas por haber simplificado el código al mínimo, introduciendo con ello ciertas inexactitudes, en particular:
- los objetos pasados a la función tienen el mismo tamaño (código actualizado);
- en lugar de la salida tonta printf("1");/printf("2"); en realidad se accede directamente a la interfaz o a los internos del objeto, lo que a su vez no permite inlinear dos algoritmos en una sola función de llamada (código actualizado).

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      uint Type(){return 0x778F6712;}
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      if (a.Type()== d1.Type()) test(a,d1.Get(),d2.Get());
      else {
      printf("2");
      d1.set(d2.get());}
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   uint Type(){return 0x308FD7FE;}
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b, b, b);    // 1      should be: 1
   c.test(b, d, d);    // 2      should be: 2   
}


O así:

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      printf("2");
      d1.set(d2.get());
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b.Get(), b.Get(), b.Get());    // 1      should be: 1
   c.test(b.Get(), d.Get(), d.Get());    // 2      should be: 2   
}
 
Gracias por la solución,
no es lo ideal ya que requiere cambios en la estructura de los objetos utilizados y ensucia la lógica, pero funciona.

Y sí, es mejor hacer una función envolvente sobre test:
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
A continuación, busque en el proyecto todas las llamadas:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
De todos modos, muchas gracias por tu ayuda.
 
Sergey Dzyublik:
Gracias por la solución,
No es lo ideal porque requiere cambios en la estructura de los objetos utilizados y ensucia la lógica, pero funciona.

Y sí, mejor hacer una función envolvente sobre test:
que buscar en el proyecto todas las llamadas:

De todos modos, muchas gracias por tu ayuda.

Sí, estoy de acuerdo.

 

Defectos en el funcionamiento de la caché de la función/clase de la plantilla:
(no se ha solucionado con MT5(build 2345)) ** Comportamiento indefinido, creas un objeto complejo envuelto con el tipo interno "C" varias veces y resulta ser un tipo de datos completamente diferente, quizás "B", quizás "int", lo que quieras...
(no se ha solucionado con MT5(build 2345)) * Error de compilación, error al pasar un puntero de función como argumento de plantilla const ref.
(no se ha solucionado con MT5(build 2345)) * Error de compilación, el objeto B<int> puede ser creado después del objeto de clase B<void*>, pero se produce un error de compilación si se hace antes.


Defectos en el trabajo de la función/clase de la plantilla:
(no se ha solucionado con MT5(build 2345)) ** Error de compilación, error dentro de la función de plantilla, el puntero pasado dentro de la operación deconversión de tipo explícito se comporta como una clase, de lo contrario como un puntero.
(no se ha solucionado con MT5(build 2345)) ** Error de compilación, error con la generación de código de la clase de la plantilla mientras se utiliza la clase interna.
(no se ha solucionado con MT5(build 2345)) ** Error de compilación, error al intentar acceder a la clase interna para el parámetro de plantilla de la función de plantilla.
(no se ha solucionado con MT5(build 2345)) ** Error de compilación, error al generar el método/clase de la plantilla, el proceso de "autocompletado" del parámetro de la plantilla se sale del ámbito del código del programa principal.
(no se ha solucionado con MT5(build 2345)) * Error de compilación, error con la ausencia de autogeneración del código de la clase de la plantilla cuando la clase de la plantilla actúa como valor de retorno para el método de la plantilla.
(no se ha solucionado con MT5(build 2345)) * Error de compilación, error en la definición de la clase interna - no hay referencia al espacio de nombres global cuando se define una clase base.
(no se ha solucionado con MT5(build 2345)) *(nuevo) Error de compilación, error al pasar una estructura interna a una función de plantilla, eltipo de datos resultante no puede utilizarse como tipo de datos base para otra estructura interna en la clase de plantilla.
(no se ha solucionado con MT5(build 2345)) *(nuevo) Error de compilación, un error al llamar a una función de plantilla con tipos de argumentos explícitos cuando se llama desde una función no de plantilla sobrecargada.


Defectos en el desajuste de la prioridad de las llamadas a funciones sobrecargadas en MQL en comparación con C++:
(no se ha solucionado con MT5(build 2345)) *** Error de compilación cuando hay herencia de clases A <= B <= C <= D y se implementan dos funciones de sobrecarga, por ejemplo, una con parámetro A* y otra con parámetro B*, entonces al pasar en dicha función un objeto C* o D* en MQL se produce un error de compilación "llamada ambigua a función sobrecargada".
(no se ha solucionado con MT5(build 2345)) ** Tiempo de ejecución, desajuste de prioridades en las llamadas a funciones de plantilla sobrecargadas.
(no solucionado por MT5(build 2345)) **(nuevo) Error de compilación, la prioridad de las llamadas de las funciones de plantilla sobrecargadas depende en realidad del tipo de parámetro de la plantilla, lo que teóricamente no debería afectar al resultado de la compilación.
(no se ha solucionado con MT5(build 2345)) **(nuevo) Error de compilación, se produce un error de compilación al generar código para una función de plantilla a pesar de que existe una función de plantilla sobrecargada con una firma adecuada para los parámetros pasados.



Sugerencias:
ref- al permitir que los literales y las variables temporales se pasen como argumentos const ref a una función.
enlace- cuando semueven los archivos del proyecto en la pestaña Proyecto, para los archivos movibles que están abiertos y en las pestañas ME, actualiza su ruta de ubicación automáticamente.
link- para introducir la funcionalidad de la declaración typedef en MQL.
link- sobre la posibilidad de forzar la generación de constructores de copia y operadores de asignación por defecto.

 

Sergey Dzyublik:
Спасибо за вариант решения

el enlace es una copia temporal, por lo que no se puede cambiar la estructura

 
Andrei Trukhanovich:
La referencia es una copia temporal, por lo que no se puede cambiar la estructura

Tiene razón en el caso general...
Pero en casos particulares es mucho más complicado y de hecho las estructuras dadas son iteradores y no es su contenido lo que se cambia, sino los objetos a los que se refieren.
Así que el problema está resuelto en el caso especial y se lo agradezco.

 
Bug MT5 (build 2345) muchos defectos relacionados con la devolución del objeto "en el lugar creado" cuando el objeto es una clase/estructura de plantilla:

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

A test_a_class_class(){
   return A(1,2,3);                //OK
};

A test_a_ptr_class(){
   return &A(1,2,3);               //OK
};


template<typename T>
class B{
public:
   B(int &){}
   B(long){}
   B(int, int, int){};  
   B(const B&){}
   B(const A*){}
};

// template class type
B<A*> test_b_class_class(){
   B<A*> b(1);
   int x = 22;
   
   return B<A*>();              // Compile Error: ambiguous call to overloaded function with the same parameters: "B(long)" and "B(const A*)"
   return B<A*>(1,2,3);         // Compile Error: only one argument is acceptable, argument should be castable to int
   return B<A*>(x);             // Compile Error: argument is passed by value instead of by reference.
   return B<A*>((A*)NULL);      // Compile Error: 'int' - invalid cast operation        
   return B<B<B<long>>>(1);     // Compile Error: OK, template parameter type does not provide any effort on compilation result
   
   return b;
};

B<A*>* test_b_ptr_ptr(){
   B<A*> b(1);
   
   return &B<A*>(1);            // Compile Error: '&' - illegal operation use
   return &b;                 
};


void OnStart (){ 
   // simple class type
   A* a_ptr = test_a_ptr_ptr();
   A a0 = test_a_class_class();
   A a1 = test_a_ptr_class();
   
   // template class type
   B<A*> b0 = test_b_class_class();
   B<A*>* b_ptr = test_b_ptr_ptr();
}
 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

Sergey Dzyublik, 2020.03.01 12:53

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

Si entiendo bien, ¿esta función devolverá el puntero al objeto que no existe?

 
fxsaber:

¿Entiendo correctamente que esta función devolverá un puntero a un objeto inexistente?

Sí, en este ejemplo la función devolverá un puntero a un objeto inexistente.
El propósito principal de este código es mostrar que hay funcionalidad de trabajo para una clase simple y al mismo tiempo no hay ninguna para una clase de plantilla.

Razón de la queja: