Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 - страница 11

 

Просьба добавить функцию "Скопировать блок ошибок"

Пример. Я тут мучаю ИИ по конвертации с mq4 на mq5. Шло нормально, пока не потребовалось впилить некоторые модули и тут ошибки.

//без комментариев по ИИ и по тому, какой грязный пишет код, речь не об этом


Для удобства исправления требутся создать некий текстовый блок с ошибками, чтобы можно было копировать ИЛИ автоматически направлять Агенту ИИ (в перспективе, включая автоконвертацию после исправления).


Пример текстового блока по строкам:


[номер строки] [полный текст кода в этой строке]

[перечисление всех ошибок для этой строки]


Казалось бы, это стандарт - скопировать "отчёт" по ошибкам.

 
Vitaliy Kuznetsov #:

Просьба добавить функцию "Скопировать блок ошибок"

Пример. Я тут мучаю ИИ по конвертации с mq4 на mq5. Шло нормально, пока не потребовалось впилить некоторые модули и тут ошибки.

//без комментариев по ИИ и по тому, какой грязный пишет код, речь не об этом

 

Для удобства исправления требутся создать некий текстовый блок с ошибками, чтобы можно было копировать ИЛИ автоматически направлять Агенту ИИ (в перспективе, включая автоконвертацию после исправления).


Пример текстового блока по строкам:


[номер строки] [полный текст кода в этой строке]

[перечисление всех ошибок для этой строки]


Казалось бы, это стандарт - скопировать "отчёт" по ошибкам.

Подписываюсь. 

С тем же сталкиваюсь КАЖДЫЙ ДЕНЬ. 

Поначалу хотел зайти "в журнал", думал, как в терминале, мол - можно подробнее посмотреть и скопировать. 

Ан нет, неудобно без полного копирования. 

 
Ilyas #:
Будет оператор using, который решит проблему ограничения функционала (сделает поведение компилятора "как раньше")
Смысл сокрытия родительских функций, если они public, вообще не понятен.
Поясните, какую задачу решает такое поведение компилятора.
 
fxsaber #:

Спасибо.

Согласен. Но в MQL5 иногда приходилось писать гадкие костыли, чтобы обойти ограничения языка. Например, предложенный Вами проброс, но в обратном направлении. Это нужно для обхода ограничения указателей на функции: нельзя сделать указатель на статический метод.


Чтобы не быть голословным, библиотека TypeToBytes компилировалась без предупреждений. Сейчас - черт ногу сломит.

Спасибо, проверил код библиотеки.


Основная ошибка в коде связана с обнулением на декларации: 

T X={0};  

псевдокод 

X.Field1 = 0;                                          // инициализация первого поля (для него, в качесвте инициализатора явно задана константа ноль)
memset(X.RestFields, 0, sizeof(X) - sizeof(X.Field1)); // обнуление остальных полей T


Правильная запись обнуления:

T X={};

псевдокод

memset(X, 0, sizeof(X)); // обнуление


Я внёс необходимые изменения, проверте пожалуйста исполнение теста на правильность (корректность вывода) .

Файлы:
mql5.zip  9 kb
 
Sergey Gridnev #:
Смысл сокрытия родительских функций, если они public, вообще не понятен.
Поясните, какую задачу решает такое поведение компилятора.

Пожалуйста, не надо разводить холивар, если есть аргументы - приведите их

Данное изменение связано с работой над новой версией MQL компилятора, которая активно ведётся.


скоп = область видимости

задачи:

  1. Однозначность при резолвинге имени внутри скопа.

    Если в скопе имеется сущность с искомым именем, то используется эта сущность (не ищем с таким же именем в родительских скопах).
    Стало как в С++, поэтому можно будет использовать коды С++ без опаски, что поведение кода изменится из-за разного резолвинга.

  2. Улучшает инкапсуляцию

    Класс переопределяет функцию из родитеского скопа, чтобы обеспечить нужный способ обработки данных этого класса (родитель ничего не знает про потомков).
    Если неоходимо использовать сущность с таким же именем из родительского скопа - укажите это явно.
    struct A
      {
       int x;
    
       double operator+(double y) { Print(__FUNCSIG__); return(x+y); }
      };
      
    struct B : public A
      {
       int operator+(int y) { Print(__FUNCSIG__); return((int)A::operator+(y)); }
      };
       
    void OnStart(void)
      {
       B b;
    
       b+100;                  // OK, B::operator+(int)
       b+M_PI;                 // warning, cast double to int for B::operator+(int)
       
       b.A::operator+(M_PI);   // OK, A::operator+(double)
      }
    
    При необходимости, можно будет использовать ключевое слово using (в разработке).


ИТОГО:
  Оба подхода имеют право на жизнь, но старый резолвинг имени позволял обеспечить только одно поведение с перегрузкой, без сокрытия.
  Новые правила резолвинга с оператором using позволят использовать оба подхода (сокрытие или перегрузка) и только для тех методов, которым это явно необходимо.

Перегрузку функций, следует использовать только в случае необходимости, там где она явно нужна, а не просто потому что может быть использована.
Общее правло, чем меньше одинаковых имён у разных сущностей - тем лучше.
 
Ilyas #:
Пожалуйста, не надо разводить холивар, если есть аргументы - приведите их
Когда для класса A создаётся класс-потомок B, это означает, что "B является A" и совершенно не логично, что у класса B не стало методов класса A из-за того, что произошло расширение перегруженных методов на один.

PS. Лучше бы интерфейсы реализовали.
 
Sergey Gridnev #:
Когда для класса A создаётся класс-потомок B, это означает, что "B является A" и совершенно не логично, что у класса B не стало методов класса A из-за того, что произошло расширение перегруженных методов на один.

PS. Лучше бы интерфейсы реализовали.

Интерфейсы есть

Подозреваю, что речь идет о множественном наследовании? 
Оно пока отложено.

И кстати, для резолвинга при множественном наследовании тоже есть нюансы, если в 2-ух и более родителях имеются одинаковые сигнатуры функции, какую вызывать? 
По очереди наследования? 
Очередь наследования поменялась = изменилось поведение...

 
Ilyas #:
Интерфейсы есть
То что у вас есть под названием "интерфейс" на самом деле является абстрактным классом.

 
Ilyas #:
Подозреваю, что речь идет о множественном наследовании? 
Оно пока отложено.
Интерфейсы, как раз таки, решают проблему множественного наследования.
Не может класс B являться классами A, C, D, но класс B может являться классом A и реализовывать интерфейсы I1 и I2.
 
Ilyas #:
И кстати, для резолвинга при множественном наследовании тоже есть нюансы, если в 2-ух и более родителях имеются одинаковые сигнатуры функции, какую вызывать? 
Вот, кстати, ради избегания подобной ситуации и введено понятие "интерфейс".