Fehler, Irrtümer, Fragen - Seite 2722

 
A100:

Im Prinzip sollte es einen solchen Fall nicht geben - das Problem sollte auf der Compiler-Ebene (wie in C++) gelöst werden. Und in diesem Fall ist es durchaus möglich, weshalb sich die Diskussion über mehrere Seiten hinzieht

Eindeutig ein Fehler... Aber es muss sein! )))

Imho müssen konstante Ausdrücke zur Kompilierzeit bekannt sein und statische Ausdrücke müssen während der Initialisierung der Anwendung in der Beschreibungssequenz bekannt sein.

und dieses Schema in MQL, wo es eine Art Konstantensteuerung gibt, aber ich kann zur Laufzeit selbst eine Konstante zuweisen, und ich kann einen Funktionsaufruf als Initialisierung verwenden:

struct A
{
   const double a;
   A():a(AccountInfoDouble(ACCOUNT_BALANCE))
   {
      Print("a = ", a); // a = 9999.290000000001
   }
};
//+------------------------------------------------------------------+
void OnStart()
{
   A a1;
}
//+------------------------------------------------------------------+

und diese "Konstante" könnte in lokaler Sichtbarkeit sein.... ab wann wird sie zu einem konstanten Ausdruck und wie hilft sie.... ich weiß nicht, ich verstehe es nicht ohne Handbücher, es gibt keine Beschreibung des Speichermodells - es hat keinen Sinn, gut, höchstens, verwenden Sie, wie es sein sollte - initialisieren mit Konstante in allen Konstruktoren, dann wird der Compiler helfen Warnung, wenn Sie versehentlich entscheiden, dieses Feld in der Zukunft zu ändern

 
Igor Makanu:
Aber dieses Schema in MQL, wo es eine Art von Kontrolle über Konstanten, aber ich kann Konstanten in zufälligen Modus selbst zuweisen

Wie oft kann man sich noch für seine Unkenntnis der Grundlagen von C++ schämen?

 

dieses Beispiel überhaupt nicht verwirrend ist:

struct A
{
   const double a;
   A():a(SymbolInfoDouble(_Symbol,SYMBOL_ASK))
   {
      Print("a = ", a);
   }
};
void OnTick()
  {
   const A a;
  }
//+------------------------------------------------------------------+

2020.04.23 21:40:04.474 tst (EURUSD,H1) a = 1.07892

2020.04.23 21:40:04.546 tst (EURUSD,H1) a = 1.07893

2020.04.23 21:40:04.585 tst (EURUSD,H1) a = 1.07893

2020.04.23 21:40:05.254 tst (EURUSD,H1) a = 1.07893

2020.04.23 21:40:05.305 tst (EURUSD,H1) a = 1.07893

2020.04.23 21:40:05.306 tst (EURUSD,H1) a = 1.07892

 
Stanislav Korotky :

Es gibt zwei Programme, die gleichzeitig an der gleichen Datei arbeiten. Beim Schreiben werden die Flags FILE_READ|FILE_WRITE|FILE_BIN|FILE_SHARE_READ verwendet, beim Lesen - FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ. Obwohl das erste Programm die Datei regelmäßig mit FileFlush speichert, sieht das zweite Programm die Länge der Datei nur, wenn sie geöffnet wird. Ich habe versucht, FileSeek hin und her zu schieben - es hilft nicht.

Frage: Wie bringe ich das Programm, das die Datei liest, dazu, die Daten, die neu geschrieben werden, zu übernehmen?

Dies scheint ein Fehler zu sein, er wurde vor einiger Zeit im englischen Forum gemeldet. Ich hatte keine Zeit, hier darüber zu berichten.

Lesen die Entwickler nicht das englische Forum?

 
Stanislav Korotky:

Es gibt zwei Programme, die gleichzeitig an der gleichen Datei arbeiten. Das schreibende Programm verwendet die FlagsFILE_READ|FILE_WRITE|FILE_BIN|FILE_SHARE_READ. Derjenige, der liest - FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ. Obwohl das erste Programm die Datei regelmäßig mit FileFlush speichert, sieht das zweite Programm die Länge der Datei nur, wenn sie geöffnet wird. Ich habe versucht, FileSeek hin und her zu schieben - es hilft nicht.

Frage: Wie bringe ich das Programm, das die Datei liest, dazu, die zu überschreibenden Daten zu übernehmen?

Befinden sich die beiden Programme in demselben Terminal oder in zwei verschiedenen Terminals?

 

Objektmethoden aus einem per Referenz übergebenen Objektarray funktionieren nicht.

Beispiel:

//+------------------------------------------------------------------+
//| Пример: добавленный метод для расширения файла ..\Include\String\String.mqh
//|--
//| Получает из указанной строки подстроки по заданному разделителю 
//| и возвращает количество полученных объектов-подстрок
//|         НЕ РАБОТАЕТ !!!!!!!!!!
//+------------------------------------------------------------------+
int CString::Split(const string separator,      // разделитель
                   CString      &result[] )     // массив строковых объектов
  {
   string tmp_result[];               

   if(StringLen(separator)==0) return(0);

   ushort u_sep=StringGetCharacter(separator,0); 
   
   int count=StringSplit(m_string,u_sep,tmp_result);

   // временно для проверки
   result[0].Assign("Buy"); // НЕ РАБОТАЕТ !!!!!!
   Alert("ressult[0] = ",result[0].Str()); // <--- уже не отрабатывает
   // конец временно
   
   /*
   for(int i=0;i<count;i++)
     {
      result[i].Assign(tmp_result[i]); // НЕ РАБОТАЕТ !!!!!
     };
   */
   
   return(count);
  }
//+------------------------------------------------------------------+
 
Slava:

Befinden sich diese beiden Programme in demselben Terminal oder in zwei verschiedenen Terminals?

In einem Terminal. Der Experte schreibt die Daten, der Indikator liest die Daten. Sie hängen an verschiedenen Karten, könnten aber natürlich auch an derselben hängen (falls das eine Rolle spielt). Build 2380.

 

VS2019

#include <iostream>

int x;

struct A 
{
    const int a;
    A() :a(x) {}
};
int main()
{
    std::cout << "x = ";
    std::cin >> x;
    const A a;
    std::cout << "a.a = " << a.a;
}

x = 12345

a.a = 12345

hmm, alles funktioniert wie in MQL5

OK, ich nehme es zurück, es lässt sich nicht in Sharp kompilieren.

 
Vict:

Nun, Sie haben auch einen Konstruktor. Das bleibt natürlich Ihnen überlassen, aber Strukturen sind C-Entitäten, das Modell dort ist anders - passive Entitäten mit externer Logik (Funktionen).

Nicht unbedingt. Warum C? Was ist mit C#? - Alle Reden über passive Strukturen sind imho archaische Begriffe. Ich glaube, dass zumindest jeder Typ einen Konstruktor haben muss. Uninitialisierte Felder sind ein Übel, das vermieden werden muss.

In Ihrem Fall müssen Sie eine Factory-Methode erstellen, um ein Array von Strukturen zu erstellen, d.h. etwas wie dieses:

struct A
{
  const int a;
  A(int init_value) : a(init_value) { }

  static bool CreateArray(A &array[], int count, int init_value)
  {
    //...
  }
};

Und es gibt bereits eine der zuvor vorgeschlagenen Möglichkeiten, Array-Elemente zu füllen.

 

Ich bin auf folgendes Problem gestoßen. Der Indikator zeichnet Kerzen

Sie wird in das Diagramm eingezeichnet. Es gibt auch einen Expert Advisor, der die Puffer des Indikators liest

Also loggte ich mich ein und überflog die Phasen und fand heraus, dass der Indikator oft Kerzen mit einer Verzögerung zeichnet.

Das bedeutet, dass vor einigen Ticks (bis zu ein paar Minuten genau) die Puffer bereits berechnet und aktualisiert wurden und der Expert Advisor Daten aus ihnen liest

(beide Eulen und der Indikator schreiben es ins Protokoll). Aber wir sehen das alte Bild auf dem Chart. Dieser Screenshot wurde zum Beispiel zu dem Zeitpunkt aufgenommen, als der rote Balken den Tiefpunkt des vorherigen durchbrochen hat. Aber auf dem Diagramm sehen wir nur den vorherigen roten und den untergezeichneten grünen Balken (er ist in der Tat um zwei Balken größer).


Und hier ist das eigentliche Bild, es wurde später gezeichnet. Wir sehen die Panne, sie hat die Aufnahme des Screenshots ausgelöst. Den Protokollen zufolge ist alles in Ordnung.



Wer kann mir sagen, was das Problem ist und wie ich die Aktualisierung des Diagramms beschleunigen kann? Ich rufe die FunktionChartRedraw aus dem EA auf, aber es gibt immer noch eine Verzögerung von ein paar Minuten.

Zwei Minuten sind ein bisschen viel, ich kann mir den Grund gar nicht vorstellen. Berechnungen sind nicht so kosmisch, dass sie sich so stark verlangsamen.