Wenn Sie immer noch nicht verstehen, worum es hier geht, lesen Sie wahrscheinlich meine Beiträge nicht aufmerksam. Mein Appell richtet sich an die Entwickler, nicht an Sie. Ich brauche Ihre billigen Ratschläge nicht.
Beruhigen Sie sich und machen Sie sich nicht so viele Sorgen.
Einmal mehr bin ich davon überzeugt, dass Menschen mit einer geringen Gehirnentwicklung in der Regel wenig Verständnis für Höflichkeit haben.
Sie können nicht einmal verstehen, was man Ihnen sagt, und Sie sind so unhöflich wie ein Kindergartenkind, das noch nicht einmal gelernt hat, richtig zu schreiben.
Leider, oder vielleicht auch zum Glück, mache ich keine direkte Entwicklung, Es ist jedoch die Arbeit an den Projekten, die es Ihnen ermöglicht, die Fähigkeiten der Sprache zu bewerten und ihre Mängel und Bugs zu entdecken...
Früher wurden bei der Arbeit an MQL-Projekten die Informationen über Fehler (Bugs) in der Reihenfolge ihrer Entdeckung bereitgestellt. Jetzt haben wir beschlossen, einen neuen Ansatz zu versuchen - wir arbeiten uns bis zu einem blockierenden Fehler vor und stellen dann Informationen über alle gefundenen Fehler zur Verfügung.
#ifdef __cplusplus
#include <iostream>
#endif
#define PRINT(x) ; Print(#x, ":", string(x))
template<typename T>
class main_wrapper{
public:
T data;
};
template<typename T>
class external_wrapper{
public:
T data;
};
template<typename T>
class A{
public:
class internal_wrapper : public external_wrapper<T> {};
main_wrapper<internal_wrapper> internal_wrapper_0;
main_wrapper<external_wrapper<T>> external_wrapper_0;
A(){
main_wrapper<internal_wrapper> internal_wrapper_1;
main_wrapper<external_wrapper<T>> external_wrapper_1;
#ifdef __MQL5__
PRINT(__FUNCSIG__);
PRINT(typename(internal_wrapper_0.data.data)); // (Bug) int int
PRINT(typename(external_wrapper_0.data.data)); // (OK) int B*
PRINT(typename(internal_wrapper_1.data.data)); // (Bug) int int
PRINT(typename(external_wrapper_1.data.data)); // (OK) int B*#endif
}
};
class B{
char data[10];
};
class C{
char data[1000];
};
voidOnStart()
{
A<int> val_int;
A<B*> val_ptr;
printf("%d\n", sizeof(main_wrapper<A<B>::internal_wrapper>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is usedprintf("%d\n", sizeof(main_wrapper<A<C>::internal_wrapper>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
}
int main(){
OnStart();
return1;
}
Sehr unangenehmer MT5(build 2316) Bug, der die weitere Entwicklung blockiert. Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...
Ich habe viel Zeit und Mühe investiert, um herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML) Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird. Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.
Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
class A{
public:
class B{};
};
template<typename T>
class wrapper{
public:
T data;
};
template<typename T>
class wrapped_B{
public:
A::B data;
};
voidOnStart()
{
A::B a; // OK
wrapper<A::B> b0; // 'B' - unexpected token, probably type is missing? 'data' - semicolon expected
wrapped_B<A::B> b2; // OKclass local_B : public A::B{};
wrapper<local_B> b1; // OK
}
int main(){
OnStart();
return0;
}
Ein weiterer MT5(build 2316) Fehler bei der Generierung von Template-Klassencode bei Verwendung einer internen Klasse. C++ online:https://onlinegdb.com/HJkKXAqMU
template<typename T>
class type_wrapper{
T data;
};
template<typename T>
class A{
class type_wrapper : public:: type_wrapper<T>{}; // '::' - syntax error
};
voidOnStart()
{
A<int> a;
}
int main(){
OnStart();
return0;
}
Ein weiterer Fehler inMT5 (Build 2316), der mit derinternen Klasse zusammenhängt, ist die fehlende Möglichkeit, explizit auf den globalen Namespace zu verweisen. C++ online:https://onlinegdb.com/H14NF05G8
Sergey Dzyublik: Ein sehr unangenehmer Fehler, der die weitere Entwicklung blockiert. Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...
Es hat mich viel Zeit und Mühe gekostet, herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML) Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird. Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.
Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
#ifdef __cplusplus
#include <iostream>
#endif
#define PRINT(x) ; Print(#x, ":", string(x))
template<typename T>
class main_wrapper{
public:
T data;
};
template<typename T>
class external_wrapper{
public:
T data;
};
template<typename T>
class A{
public:
template<typename T1>
class internal_wrapper : public external_wrapper<T1> {};
main_wrapper<internal_wrapper<T>> internal_wrapper_0;
main_wrapper<external_wrapper<T>> external_wrapper_0;
A(){
main_wrapper<internal_wrapper<T>> internal_wrapper_1;
main_wrapper<external_wrapper<T>> external_wrapper_1;
#ifdef __MQL5__
PRINT(__FUNCSIG__);
PRINT(typename(internal_wrapper_0.data.data)); // (Bug) int int
PRINT(typename(external_wrapper_0.data.data)); // (OK) int B*
PRINT(typename(internal_wrapper_1.data.data)); // (Bug) int int
PRINT(typename(external_wrapper_1.data.data)); // (OK) int B*#endif
}
};
class B{
char data[10];
};
class C{
char data[1000];
};
voidOnStart()
{
A<int> val_int;
A<B*> val_ptr;
printf("%d\n", sizeof(main_wrapper<A<B>::internal_wrapper<B>>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is usedprintf("%d\n", sizeof(main_wrapper<A<C>::internal_wrapper<C>>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
}
Danke, in der Tat umgeht die Einführung eines Dummy-Parameters für die Vorlage im Fall des Beispiels das Problem. Bei dem globalen Projekt ist es jedoch etwas komplizierter:Die interne Klasse wurde als Alternative zur fehlenden typedef typename-Funktionalität verwendet, um sowohl den Entwicklungsprozess als auch die Anwendung der endgültigen Containerklasse zu vereinfachen. Es könnte sich lohnen, auf eine Korrektur durch die Entwickler zu warten. Als letztes Mittel müssen alle Abhängigkeiten nach außen gezogen werden, in der Hoffnung, dass keine weitere erfolgreiche Kompilierung mit undefiniertem Verhalten zur Laufzeit erfolgt.
Um die internen Funktionen der Klasse zusammenzufassen, können wir eindeutig sagen, dass es an der Funktionalität der Typdeklaration fehlt, zumindest an ihrer primitiven Form, um sie richtig zu nutzen... Anstelle von kompaktem und klarem C++-Code:
Wir müssen einen Zaun mit #define und Vererbung durch die interne Klasse bauen:
template<typename _Tp, typename _Allocator>
class __vector_base{
public:
class allocator_type : public _Allocator{};
protected:
#define value_type _Tp
#define size_type DEFAULT_SIZE_TYPE
#define difference_type size_type
struct pointer : public allocator_type::pointer{};
struct iterator : public allocator_type::pointer{};
............................
#undef value_type
#undef size_type
#undef difference_type
};
Und hier gibt es viel mehr Probleme, als es auf den ersten Blick scheinen mag. Probleme treten auf, wenn #define als typedef-Deklaration verwendet wird:
- es gibt keine Möglichkeit, den Typ der verwendeten Daten außerhalb der Klasse zu übergeben (es gibt überhaupt keine Möglichkeit, einfache Datentypen zu übergeben); - ist es notwendig, den Geltungsbereich von #define ständig mit dem entsprechenden #undef-Paar zu kontrollieren
Probleme bei der Verwendung einer internen Klasse als typedef-Deklaration:
- es ist möglich, Klasse/Struktur-Datentypen, die außerhalb der Klasse verwendet werden, zu übergeben (einfache Datentypen können überhaupt nicht übergeben werden); - durch Vererbung gehen alle Konstruktoren verloren, sie müssen manuell mit Signaturen aus der Basisklasse neu geschrieben werden; - wenn die Klasse, in der die typedef-Deklaration verwendet wird, eine Basisklasse hat, dann gibt es durch überlappende Namensräume keine Möglichkeit, den gleichen Namen wie die typedef-Deklaration zu verwenden; - Klassen erben von Klassen, Strukturen von Strukturen, dies muss ständig kontrolliert werden;
Durch die Einführung von Standard-Zuweisungsoperatoren ergab sich die Notwendigkeit, die zufällige Ausführung von Zuweisungen für die Basisklasse zu verbieten. Die Entwickler haben zu diesem Zweck "operator= delete" hinzugefügt. Es erscheint jedoch nicht logisch, die Verknüpfung "Löschen/Standard" zu unterbrechen, weil dann alles wieder manuell geschrieben werden muss. Vielleicht mache ich etwas falsch?
class Base{
char base_data[100];
};
template<typename T>
class A : public Base{
int data_1;
int data_2;
int data_3;
int data_4;
int data_5;
int data_6;
int data_7;
int data_8;
int data_9;
char arr_1[];
char arr_2[];
public:
// MQL
A* operator=(A &obj){
data_1 = obj.data_1;
data_2 = obj.data_2;
data_3 = obj.data_3;
data_4 = obj.data_4;
data_5 = obj.data_5;
data_6 = obj.data_6;
data_7 = obj.data_7;
data_8 = obj.data_8;
data_9 = obj.data_9;
ArrayCopy(arr_1, obj.arr_1);
ArrayCopy(arr_2, obj.arr_2);
(Base)this = obj;
return &this;
};
// C++// A& operator=(A &) = default;template<typename TT>
A* operator=(A<TT> &) = delete;
};
voidOnStart()
{
A<int> a;
A<int> b;
A<double> c;
a = b;
//a = c;
}
Ist der Schlüssel für den portablen Modus zufällig erforderlich?
Werden alle Terminals manuell gestartet?
Von Hand, ja, das tun sie alle. Letztendlich habe ich sie auf diese Weise manuell gestartet.
Die Taste für den portablen Modus ändert in dieser Hinsicht nichts.
Das Problem ist, dass MT4 ein Autorisierungsfenster ausgibt und der Programmstart nicht als abgeschlossen betrachtet wird.
Sie müssen "start" in der Batch-Datei verwenden.
Alles in allem stelle ich fest, dass ich die Sache gut im Griff habe.
Vielen Dank für Ihre Teilnahme!
Wenn Sie immer noch nicht verstehen, worum es hier geht, lesen Sie wahrscheinlich meine Beiträge nicht aufmerksam. Mein Appell richtet sich an die Entwickler, nicht an Sie. Ich brauche Ihre billigen Ratschläge nicht.
Beruhigen Sie sich und machen Sie sich nicht so viele Sorgen.
Einmal mehr bin ich davon überzeugt, dass Menschen mit einer geringen Gehirnentwicklung in der Regel wenig Verständnis für Höflichkeit haben.
Sie können nicht einmal verstehen, was man Ihnen sagt, und Sie sind so unhöflich wie ein Kindergartenkind, das noch nicht einmal gelernt hat, richtig zu schreiben.
Es ist jedoch die Arbeit an den Projekten, die es Ihnen ermöglicht, die Fähigkeiten der Sprache zu bewerten und ihre Mängel und Bugs zu entdecken...
Früher wurden bei der Arbeit an MQL-Projekten die Informationen über Fehler (Bugs) in der Reihenfolge ihrer Entdeckung bereitgestellt.
Jetzt haben wir beschlossen, einen neuen Ansatz zu versuchen - wir arbeiten uns bis zu einem blockierenden Fehler vor und stellen dann Informationen über alle gefundenen Fehler zur Verfügung.
Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...
Ich habe viel Zeit und Mühe investiert, um herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird.
Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.
Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
Ein weiterer MT5(build 2316) Fehler bei der Generierung von Template-Klassencode bei Verwendung einer internen Klasse.
C++ online:https://onlinegdb.com/HJkKXAqMU
Ein weiterer Fehler inMT5 (Build 2316), der mit derinternen Klasse zusammenhängt, ist die fehlende Möglichkeit, explizit auf den globalen Namespace zu verweisen.
C++ online:https://onlinegdb.com/H14NF05G8
Ein sehr unangenehmer Fehler, der die weitere Entwicklung blockiert.
Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...
Es hat mich viel Zeit und Mühe gekostet, herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird.
Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.
Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
Ist das der richtige Weg?
Danke, in der Tat umgeht die Einführung eines Dummy-Parameters für die Vorlage im Fall des Beispiels das Problem.
Bei dem globalen Projekt ist es jedoch etwas komplizierter:Die interne Klasse wurde als Alternative zur fehlenden typedef typename-Funktionalität verwendet, um sowohl den Entwicklungsprozess als auch die Anwendung der endgültigen Containerklasse zu vereinfachen.
Es könnte sich lohnen, auf eine Korrektur durch die Entwickler zu warten.
Als letztes Mittel müssen alle Abhängigkeiten nach außen gezogen werden, in der Hoffnung, dass keine weitere erfolgreiche Kompilierung mit undefiniertem Verhalten zur Laufzeit erfolgt.
Um die internen Funktionen der Klasse zusammenzufassen,
können wir eindeutig sagen, dass es an der Funktionalität der Typdeklaration fehlt, zumindest an ihrer primitiven Form, um sie richtig zu nutzen...
Anstelle von kompaktem und klarem C++-Code:
Wir müssen einen Zaun mit #define und Vererbung durch die interne Klasse bauen:
Probleme bei der Verwendung einer internen Klasse als typedef-Deklaration:Und hier gibt es viel mehr Probleme, als es auf den ersten Blick scheinen mag.
Probleme treten auf, wenn #define als typedef-Deklaration verwendet wird:
Die Entwickler haben zu diesem Zweck "operator= delete" hinzugefügt.
Es erscheint jedoch nicht logisch, die Verknüpfung "Löschen/Standard" zu unterbrechen, weil dann alles wieder manuell geschrieben werden muss.
Vielleicht mache ich etwas falsch?