Fehler, Irrtümer, Fragen - Seite 2661

 
Nikolai Semko:

Ich entschuldige mich dafür, dass ich den Code auf ein Minimum vereinfacht habe und dadurch einige Ungenauigkeiten entstanden sind:
- die an die Funktion übergebenen Objekte die gleiche Größe haben (Code aktualisiert);
- anstelle der stummen Ausgabe printf("1");/printf("2"); auf die Schnittstelle oder die Objektinterna wird tatsächlich direkt zugegriffen, was wiederum nicht erlaubt, zwei Algorithmen in eine einzige Aufruffunktion einzubinden (Code aktualisiert).

 
Sergey Dzyublik:

Ich entschuldige mich dafür, dass ich den Code auf ein Minimum vereinfacht habe und dadurch einige Ungenauigkeiten entstanden sind:
- die an die Funktion übergebenen Objekte die gleiche Größe haben (Code aktualisiert);
- anstelle der stummen Ausgabe printf("1");/printf("2"); auf die Schnittstelle oder die Objektinterna wird tatsächlich direkt zugegriffen, was wiederum nicht erlaubt, zwei Algorithmen in eine einzige Aufruffunktion einzubinden (Code aktualisiert).

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   
}


Oder so:

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   
}
 
Danke für die Lösung,
es ist nicht ideal, da es Änderungen in der Struktur der verwendeten Objekte erfordert und die Logik verschmiert, aber es funktioniert.

Und ja, es ist besser, eine Wrapper-Funktion über test zu machen:
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
Suchen Sie dann im Projekt nach allen Aufrufen:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
Auf jeden Fall vielen Dank für Ihre Hilfe.
 
Sergey Dzyublik:
Vielen Dank für die Lösung,
Es ist nicht ideal, weil es Änderungen in der Struktur der verwendeten Objekte erfordert und die Logik verwischt, aber es funktioniert.

Und ja, es ist besser, eine Wrapper-Funktion über test:
zu erstellen, als das Projekt nach allen Aufrufen zu durchsuchen:

Auf jeden Fall vielen Dank für Ihre Hilfe.

Ja, ich stimme zu.

 

Defekte in der Template-Funktion/Klassen-Cache-Operation:
(nicht behoben durch MT5(build 2345)) ** Undefiniertes Verhalten, Sie erstellen ein komplexes umhülltes Objekt mit internem Typ "C" mehrmals und es stellt sich heraus, dass es ein völlig anderer Datentyp ist, vielleicht "B", vielleicht "int", was immer Sie wollen...
(nicht behoben durch MT5(build 2345)) * Kompilierfehler, Fehler bei der Übergabe eines Funktionszeigers als const ref Template-Argument.
(nicht behoben durch MT5(build 2345)) * Kompilierfehler, B<int> Objekt kann nach B<void*> Klassenobjekt erstellt werden, aber Kompilierfehler tritt auf, wenn es vorher gemacht wird.


Defekte in der Funktion/Klasse der Vorlage:
(nicht behoben durch MT5(build 2345)) ** Kompilierfehler, Fehler innerhalb der Template-Funktion, übergebener Zeiger innerhalb einerexpliziten Typkonvertierungsoperation verhält sich wie eine Klasse, sonst wie ein Zeiger.
(nicht behoben durch MT5(build 2345)) ** Kompilierfehler, Fehler bei der Generierung von Template-Klassencode bei Verwendung einer internen Klasse.
(nicht behoben durch MT5(build 2345)) ** Kompilierfehler, Fehler beim Versuch, auf eine interne Klasse für einen Template-Parameter einer Template-Funktion zuzugreifen.
(nicht behoben durch MT5(build 2345)) ** Kompilierfehler, Fehler bei der Generierung von Template-Methoden/Klassen, der Template-Parameter "Autocompletion" geht aus dem Scop in den Hauptprogrammcode.
(nicht behoben durch MT5(build 2345)) * Kompilierfehler, Fehler durch fehlende automatische Generierung von Template-Klassen-Code, wenn die Template-Klasse als Rückgabewert für die Template-Methode fungiert.
(nicht behoben durch MT5(build 2345)) * Kompilierfehler, Fehler in der internen Klassendefinition - kein Verweis auf den globalen Namespace bei der Definition einer Basisklasse.
(nicht behoben durch MT5(build 2345)) *(neu) Kompilierfehler, Fehler bei der Übergabe einer internen Struktur an eine Template-Funktion, der resultierendeDatentyp kann nicht als Basisdatentyp für eine andere interne Struktur in der Template-Klasse verwendet werden.
(nicht behoben durch MT5(build 2345)) *(neu) Kompilierfehler, ein Fehler beim Aufruf einer Template-Funktion mit expliziten Argumenttypen, wenn diese von einer überladenen Nicht-Template-Funktion aufgerufen wird.


Defekte im Rahmen von überladenen Funktionsaufrufen, die in MQL nicht mit C++ übereinstimmen:
(nicht behoben durch MT5(build 2345)) *** Kompilierfehler, wenn es eine Klassenvererbung A <= B <= C <= D gibt und zwei Überladefunktionen implementiert sind, z.B. eine mit Parameter A* und eine mit Parameter B*, dann führt die Übergabe eines Objekts C* oder D* in MQL zu einem Kompilierfehler "ambiguous call to overloaded function".
(nicht behoben durch MT5(build 2345)) ** Laufzeit, Prioritätsfehlanpassung bei Aufrufen von überladenen Template-Funktionen.
(nicht behoben durch MT5(build 2345)) **(neu) Kompilierfehler, die Priorität von Aufrufen überladener Template-Funktionen hängt tatsächlich vom Typ des Template-Parameters ab, was theoretisch das Ergebnis der Kompilierung nicht beeinflussen sollte.
(nicht behoben durch MT5(build 2345)) **(new) Compile Error, ein Kompilierungsfehler tritt auf, wenn Code für eine Template-Funktion generiert wird, obwohl es eine überladene Template-Funktion mit einer passenden Signatur für die übergebenen Parameter gibt.



Vorschläge:
ref- damit Literale und temporäre Variablen als const ref Argumente an eine Funktion übergeben werden können.
Link- beimVerschieben von Projektdateien in der Registerkarte "Projekt" wird der Speicherort von Dateien, die geöffnet sind und sich in ME-Registerkarten befinden, automatisch aktualisiert.
link- zur Einführung der Funktionalität der Typdeklaration in MQL.
link- über die Möglichkeit, die Erzeugung von Standard-Kopierkonstruktoren und Zuweisungsoperatoren zu erzwingen.

 

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

der Link ist eine temporäre Kopie, so dass Sie die Struktur nicht ändern können

 
Andrei Trukhanovich:
Die Referenz ist eine temporäre Kopie, so dass Sie die Struktur nicht ändern können.

Sie haben im Allgemeinen Recht...
Aber in bestimmten Fällen ist es viel komplizierter, und die gegebenen Strukturen sind Iteratoren, und es ist nicht ihr Inhalt, der geändert wird, sondern die Objekte, auf die sie verweisen.
Das Problem ist also in diesem speziellen Fall gelöst, und dafür bin ich Ihnen dankbar.

 
Bug MT5 (Build 2345) viele Defekte im Zusammenhang mit der Rückgabe von "an Ort und Stelle erstellten" Objekten, wenn das Objekt eine Vorlagenklasse/-struktur ist:

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 zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

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

Wenn ich richtig verstehe, dann wird diese Funktion den Zeiger auf das Objekt zurückgeben, das nicht existiert?

 
fxsaber:

Verstehe ich das richtig, dass diese Funktion einen Zeiger auf ein nicht vorhandenes Objekt zurückgibt?

Ja, in diesem Beispiel wird die Funktion einen Zeiger auf ein nicht existierendes Objekt zurückgeben.
Der Hauptzweck dieses Codes ist es, zu zeigen, dass es eine funktionierende Funktionalität für eine einfache Klasse gibt und gleichzeitig gibt es keine für eine Vorlagenklasse.