Errori, bug, domande - pagina 2661

 
Nikolai Semko:

Mi scuso per aver semplificato il codice al minimo, introducendo così alcune imprecisioni, in particolare:
- gli oggetti passati alla funzione hanno la stessa dimensione (codice aggiornato);
- invece dell'output muto printf("1");/printf("2"); l'interfaccia o gli interni dell'oggetto sono effettivamente accessibili direttamente, questo a sua volta non permette di inlineare due algoritmi in una singola funzione di chiamata (codice aggiornato).

 
Sergey Dzyublik:

Mi scuso per aver semplificato il codice al minimo, introducendo così alcune imprecisioni, in particolare:
- gli oggetti passati alla funzione hanno la stessa dimensione (codice aggiornato);
- invece dell'output muto printf("1");/printf("2"); l'interfaccia o gli interni dell'oggetto sono effettivamente accessibili direttamente, questo a sua volta non permette di inlineare due algoritmi in una singola funzione di chiamata (codice aggiornato).

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 come questo:

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   
}
 
Grazie per la soluzione,
non è l'ideale perché richiede cambiamenti nella struttura degli oggetti usati e imbratta la logica, ma funziona.

E sì, è meglio fare una funzione wrapper su test:
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
Poi cerca nel progetto tutte le chiamate:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
Comunque, grazie mille per il vostro aiuto.
 
Sergey Dzyublik:
Grazie per la soluzione,
Non è l'ideale perché richiede cambiamenti nella struttura degli oggetti usati e imbratta la logica, ma funziona.

E sì, meglio fare una funzione wrapper su test:
che cercare nel progetto tutte le chiamate:

Comunque, grazie mille per il vostro aiuto.

Sì, sono d'accordo.

 

Difetti nel funzionamento della cache della funzione template/classe:
(non corretto da MT5 (build 2345)) ** Comportamento indefinito, si crea un oggetto complesso avvolto con tipo interno "C" più volte e si scopre che è un tipo di dati completamente diverso, forse "B", forse "int", qualunque cosa si voglia...
(non corretto da MT5 (build 2345)) * Errore di compilazione, bug sul passaggio di un puntatore di funzione come argomento const ref template.
(non corretto da MT5 (build 2345)) * Errore di compilazione, l'oggetto B<int> può essere creato dopo l'oggetto di classe B<void*>, ma si verifica un errore di compilazione se fatto prima.


Difetti nella funzione template/classe di lavoro:
(non corretto da MT5 (build 2345)) ** Errore di compilazione, bug all'interno della funzione template, il puntatore passato all'interno dell'operazione diconversione esplicita del tipo si comporta come una classe altrimenti come un puntatore.
(non corretto da MT5 (build 2345)) ** Errore di compilazione, bug con la generazione del codice della classe template mentre si usa la classe interna.
(non corretto da MT5 (build 2345)) ** Errore di compilazione, bug sul tentativo di accedere alla classe interna per il parametro template della funzione template.
(non corretto da MT5 (build 2345)) ** Errore di compilazione, bug sulla generazione di metodi/classi di template, il processo di "autocompletamento" dei parametri di template va fuori campo nel codice principale del programma.
(non corretto da MT5 (build 2345)) * Errore di compilazione, bug con assenza di autogenerazione del codice della classe modello quando la classe modello agisce come valore di ritorno per il metodo modello.
(non corretto da MT5 (build 2345)) * Errore di compilazione, bug nella definizione della classe interna - nessun riferimento allo spazio dei nomi globale quando si definisce una classe base.
(non corretto da MT5 (build 2345)) *(nuovo) Errore di compilazione, bug nel passaggio di una struct interna alla funzione template, iltipo di dati risultante non può essere usato come tipo di dati base per un'altra struct interna nella classe template.
(non corretto da MT5 (build 2345)) *(nuovo) Errore di compilazione, un bug quando si chiama una funzione template con tipi di argomenti espliciti quando viene chiamata da una funzione non template sovraccaricata.


Difetti nella mancata corrispondenza della priorità delle chiamate di funzioni sovraccaricate in MQL rispetto al C++:
(non corretto da MT5 (build 2345)) *** Errore di compilazione quando c'è un'eredità di classe A <= B <= C <= D e sono implementate due funzioni di sovraccarico, per esempio, una con parametro A* e una con parametro B*, allora passare in tale funzione un oggetto C* o D* in MQL causa un errore di compilazione "ambiguous call to overloaded function".
(non corretto da MT5 (build 2345)) ** Runtime, mismatch di priorità per le chiamate di funzioni template sovraccaricate.
(non corretto da MT5(build 2345)) **(nuovo) Errore di compilazione, la priorità delle chiamate di funzioni template sovraccaricate dipende in realtà dal tipo di parametro template, che teoricamente non dovrebbe influenzare il risultato della compilazione.
(non corretto da MT5 (build 2345)) **(nuovo) Errore di compilazione, un errore di compilazione si verifica quando si genera codice per una funzione template nonostante ci sia una funzione template sovraccaricata con una firma adatta ai parametri passati.



Suggerimenti:
reference- per permettere ai letterali e alle variabili temporanee di essere passati come argomenti const ref di una funzione.
link- quandosi spostano i file del progetto nella scheda Progetto, per i file spostabili che sono aperti e nelle schede ME, aggiorna automaticamente il loro percorso di localizzazione.
link- per introdurre la funzionalità della dichiarazione typedef in MQL.
link- circa la possibilità di forzare la generazione di costruttori di copia e operatori di assegnazione predefiniti.

 

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

il link è una copia temporanea, quindi non puoi cambiare la struttura

 
Andrei Trukhanovich:
Il riferimento è una copia temporanea, quindi non si può cambiare la struttura

Hai ragione nel caso generale...
Ma in casi particolari è molto più complicato e infatti le strutture date sono iteratori e non è il loro contenuto che viene cambiato, ma gli oggetti a cui fanno riferimento.
Così il problema è risolto nel caso speciale e vi sono grato per questo.

 
Bug MT5 (build 2345) molti difetti relativi al ritorno dell'oggetto "in luogo creato" quando l'oggetto è una classe/struttura modello:

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();
}
 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

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
};

Se ho capito bene, allora questa funzione restituirà il puntatore all'oggetto che non esiste?

 
fxsaber:

Ho capito bene che questa funzione restituirà un puntatore a un oggetto inesistente?

Sì, in questo esempio la funzione restituirà un puntatore a un oggetto inesistente.
Lo scopo principale di questo codice è mostrare che c'è una funzionalità funzionante per una classe semplice e allo stesso tempo non ce n'è nessuna per una classe template.