Frage zum Tippen - Seite 4

 
Ilya Malev:

Es ist nicht ganz klar, wo das Problem liegt. Könnte die Objektinitialisierung nicht in einer separaten Methode wie Init() untergebracht werden, vielleicht sogar in einer virtuellen Methode?

Ja, natürlich. Konnte nicht class.get_int()/class.get_double()/class.get_string()/... ?)). Stil, Gewohnheit ...

 
pavlick_:

Natürlich können Sie das. Konnte nicht class.get_int()/class.get_double()/class.get_string()/. ?)). Stil, Gewohnheit ...

Das können wir, aber schreiben wir d=var[x].get_double statt d=var[x], wo immer double d, var[]; vorkommt. Wenn wir schon Masochismus betreiben, sollten wir es gemeinsam tun =))

 
Ilya Malev:

Letztendlich läuft es also auf den Wunsch hinaus, in mql die Möglichkeit einzuführen, die Typisierungsoperation (auch implizit) zu überladen, d.h. einen Methodenaufrufkontext zu definieren und je nach erwartetem Rückgabetyp in diesem Kontext den erforderlichen Code aufzurufen.

Dies ist offensichtlich kein C++-Standard, und im Allgemeinen ist das Gute an C++ (und es wurde von den MQL-Entwicklern als Grundlage genommen), dass alles in C++, was der Programmierer nicht explizit handhaben konnte, er mit den Zeigern arbeiten und seinentypedef-Typ schreiben musste

ein Zeiger ist nur ein Zeiger auf eine Speicheradresse, man kann ihn immer als Parameter übergeben und ihn als Ergebnis einer Funktion erhalten, die Dereferenzierung eines Zeigers ergab einen physischen Wert in Speicherbytes, die Umwandlung eines Zeigers in seinen neuen Typ ergab viele Speicherbytes ))))

In MQL sind die Zeiger schwer zu sagen, warum, aber sie sind da, die Entwickler sagten, die Priorität ist der Datenschutz, so dass alle Innovationen, die zu Sandbox-Exits führen könnten, ausgeschlossen sind



zum Thema, leider habe ich wenig Übung im Umgang mit Vorlagen ( Template ), aber ich vermute, dass Sie das können:

1. einige überladene Funktionen schreiben, die den gewünschten Typ als Ergebnis zurückgeben und diesen Typ als Parameter annehmen, z. B. so:

//+------------------------------------------------------------------+
int f(const int x)
  {
   return((int)1);
  };
//+------------------------------------------------------------------+
double f(const double x)
  {
   return((double)2);
  }
//+------------------------------------------------------------------+
string f(const string x)
  {
   return((string)3);
  }
//+------------------------------------------------------------------+
void OnStart()
  { 
   int    a=0;
   double b=0;
   string c="0";
   a = f(a);
   b = f(b);
   c = f(c);
   Print("a = ",a);
   Print("b = ",b);
   Print("c = ",c);
}

2. jetzt muss die Funktion f() in eine Vorlage verpackt werden und den Parameter x ausblenden - wenn Vorlagen dies zulassen, dann wird der Aufruf a=f() sein - visuell wird alles schön sein, wie bei der Eingabe von

 
Igor Makanu:

es handelt sich offensichtlich nicht um einen C++-Standard

Ich glaube, Sie irren sich - obwohl ich schon lange nicht mehr in "reinem" C++ geschrieben habe, gibt es jede Menge Codebeispiele wie dieses im Internet

class A
{
public:
    operator int()const;
};

A::operator int()const
{
    return 0;
}
 
Ilya Malev:

Ich glaube, Sie irren sich - obwohl ich schon lange nicht mehr in "reinem" C++ geschrieben habe, aber das Web ist voll von Codebeispielen wie diesem

Was aber, wenn es sich um einen komplexen Typ handelt? - In C++ wurde dies durch die Verwendung von Zeigern auf ihren Typ gelöst, wobei der Compiler die Speicheradresse zurückgab und die Dereferenzierung des Zeigers sicherstellte, dass die Daten korrekt behandelt wurden

 
Igor Makanu:

Dieses Beispiel würde korrekt funktionieren, aber was ist, wenn es sich um einen komplexen Typ handelt? - In C++ wurde dies mit Zeigern auf den Typ gelöst, wobei der Compiler die Speicheradresse zurückgab und die Dereferenzierung des Zeigers für die korrekte Behandlung der Daten sorgte

Ein solches Beispiel würde in mql leider nicht korrekt funktionieren.

Ein komplexer Typ, eine Struktur oder ein Array kann überladen, was immer Sie brauchen, es erfordert keine Typkonvertierungsüberladung...

 
Ilya Malev:

In mql würde ein solches Beispiel leider nicht korrekt funktionieren.

Nun, ja, ich habe gerade gesehen, Sie wollen Typumwandlung überladen, MQL-Hilfe sagt eindeutig, dass es erlaubt ist, zu überladen, und unäre Operationen sind nur als unär und binär, bzw. überladen, ich war mit Matrizen arbeiten, versucht, ^ zu überladen - es funktioniert nicht, ich musste verwenden !

  • бинарные +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • unär +,-,++,--,~;
  • Zuweisungsoperator =;
  • Indizierungsoperator [].


Ich habe mir mein Beispiel noch einmal angesehen - der Compiler lässt es nicht zu, mein Beispiel ineine Vorlage zu verpacken. Ich kann((1/x)) zurückgeben- und ich kann eine Zeichenkette als Parameter x angeben. Normalerweise prüfen alle C-Compiler zur Kompilierzeit auf Typübereinstimmung, und MQL lässt es nicht zu, mehrdeutige Lösungen in Vorlagen zu verpacken.

Imho kann Ihr Problem - Beitrag 1 des Themas - in MQL nur dann korrekt gelöst werden, wenn alleüberladenen Funktionen beschrieben werden. Dann werden alle Typen von Variablen, die übergeben und zurückgegeben werden, und alle überladenen Funktionen zur Kompilierzeit geprüft.

 
Igor Makanu:

Ja, ich habe gerade gesehen, Sie wollen Typumwandlung überladen, MQL-Hilfe sagt eindeutig, dass Überladen erlaubt ist, und unäre Operationen sind nur als unäre bzw. binäre überladen, ich arbeitete mit Matrizen, versucht, ^ zu überladen - es funktioniert nicht, ich musste verwenden !

Ich kann zu 99% sagen, dass es keine solche Situation gibt, in der ^ nicht überladen werden kann, während ! Und die Überladungsfähigkeit hängt nicht von der Art des Operators ab. Sie müssen etwas missverstanden haben. Stellen Sie dieses Beispiel einfach hier ein, aber wenn Sie es bereits vergessen haben, lassen Sie es lieber bleiben).

Die einzige Einschränkung, die mir in Bezug auf den Operatortyp begegnet ist, ist das Verbot des Überladens der logischen Operatoren ==, !=, ! und = bei der Anwendung auf Zeiger (any_type * ). Um sie korrekt zu überladen, muss man entweder mit Autoobjekten oder Strukturen arbeiten. Gerade in den letzten Monaten habe ich eine Menge Hunde auf diesen Dingern gegessen, also kann ich getrost sprechen :)

 
Ilya Malev:

Ich kann zu 99 % sagen, dass es keine Situation gibt, in der ^ nicht überlastet wird, aber ! schon. Und die Fähigkeit zur Überlastung hängt nicht von der Art des Betreibers ab. Sie müssen etwas missverstanden haben. Stellen Sie dieses Beispiel einfach hier ein, aber wenn Sie es schon vergessen und aufgegeben haben, dann tun Sie es natürlich nicht).

Die einzige Einschränkung, die mir in Bezug auf den Operatortyp begegnet ist, ist das Verbot des Überladens der logischen Operatoren ==, !=, ! und = bei der Anwendung auf Zeiger (any_type * ). Um sie korrekt zu überladen, muss man entweder mit Autoobjekten oder Strukturen arbeiten. In den letzten Monaten habe ich eine Menge dieser Tricks gegessen, also kann ich getrost sagen :)

#include <Math\Alglib\linalg.mqh>
class Matrix
  {
public:
   CMatrixDouble     M;
   int               row;//m_strok;
   int               col;//n_stolb;
   void              Matrix(void)         {                             }
   void              Matrix(int m,int n)  { M.Resize(m,n); row=m;col=n; }
   //----      умножение матриц
   Matrix operator*(const Matrix &B){Matrix res(this.row,B.col);CAblas::RMatrixGemm(this.row,B.col,this.col,1.0,this.M,0,0,0,B.M,0,0,0,0,res.M,0,0);return(res);  }
   //----      транспонирование матрицы
   Matrix operator!(void){Matrix res(this.col,this.row);CAblas::RMatrixTranspose(this.row,this.col,this.M,0,0,res.M,0,0);return(res);                             }
   //----      нулевая матрица
   void              zeros(int r,int c) {this.M.Resize(r,c);this.row=r;this.col=c;for(int i=0;i<r;i++){for(int j=0;j<c;j++){this.M[i].Set(j,0.0);}}               }
   //----      вывод в журнал матрицы
   void MatrixPrint(string  separator="|",uint digits=3){string s,sep=" "+separator+" ";for(int i=0;i<row;i++){s=separator;for(int j=0;j<col;j++) s+=DoubleToString(M[i][j],digits)+sep;Print(s);Sleep(123);}}
private:
   void              Matrix(const Matrix &R) { this=R;                                                                                                            }
  };

Im "klassischen" Umgang mit Matrizen muss man den ^-Operator verwenden, um Matrizen zu transponieren, hier ist mein Beispiel - ich habe die SSA-Methode aus Matlab portiert, es ist die einfachste Multiplikation, Zuweisung und Transposition von Matrizen auf der Basis von CMatrixDouble - es ... er kennt die Größe der gespeicherten Matrizen nicht (wie viele Zeilen und Spalten sie hat).

 
P.S., ah, d.h. Sie wollten einen binären Operator als unären Operator überladen (2ar als 1ar), dann ja, natürlich nicht. Die einzige Ausnahme ist []