Хочется STL подобного - страница 3

 
Sergey Dzyublik:

Недели две назад занимался исcледованиями в этом направлении.
Контейнер для любого типа данных можно реализовать стандартными средствами MQL (с помощью шаблонов) без применения макросов.

На текущий момент выполнены  основные работы в сторону реализации "умного" контейнера на MQL.
Контейнер самостоятельно определяет используемый тип данных (класс, указатель, POD структура, не POD структура, string,...). Ожидается поддержка всех типов "из коробки" (за исключением union).
Так для классов, структур и указательной будет проверяться наличие реализованных операторов сравнения и равенства, а так же функций Equals, Compare.


Нужно просто реализовать нужный метод и информация о его наличии, как в случаи с operator= выше, будет использована для выбора лучшей модели поведения, например в  реализации функции поиска, проверки вхождения или сортировки.
При этом от пользователя не требуя ни каких действий по конфигурации контейнера вообще.

Основные работы по реализации заявленного функционала уже выполнены, но для их завершения необходимо:
- дождаться выхода обновления с внедрением пространства имен;
- дождаться фикса ряда багов с указателями на функции;

Ждёмс...

Касательно шаблонов. В mql не поддерживается, по крайней мере пока, перегрузка шаблонных функций/методов. Сам очень грустил, когда столкнулся.

 
Alexey Navoykov:

А зачем обращать внимание разработчиков? Разве это может причинить какие-то проблемы?  Если в коде имеется такая перегрузка, то очевидно обе функции имеют идентичный смысл, и сделаны для гибкости.  Зачем обрезать такую возможность? Занудства ради?  В MQL и так слишком мало гибкости и простора для манёвра.

А в чем возможность? В том что (2) нельзя вызвать даже явно? В этом гибкость заключается?

//Test.mqh
void f( const int  ) {} //(1)

Или в том что в следующем примере:

#include "Test.mqh" //чья то сторонняя библиотека
void f( const int& ) {} //(2)
void OnStart()
{
        int i = 5;
        f( i );
}

вместо ожидаемого пользователем вызова (2), по факту вызывается (1) ?

А может быть гибкость в том, что в следующем примере:

//Test.mqh
void f( const int& x ) { Print( x ); } //(2)
void g() { int i = 2; f( i ); }

#include "Test.mqh" //чья то сторонняя библиотека
void f( const int    ) { Print( 1 ); } //(1)
void OnStart()
{
        int i = 5;
        f( i );
        g();
}

Пользователь ничего не подозревая случайно переопределяет поведение используемой сторонней библиотеки ?

 
A100:

А в чем возможность? В том что (2) нельзя вызвать даже явно? В этом гибкость заключается?

Или в том что в следующем примере:

вместо ожидаемого пользователем вызова (2), по факту вызывается (1) ?

А может быть гибкость в том, что в следующем примере:

Пользователь ничего не подозревая случайно переопределяет поведение используемой сторонней библиотеки ?

Ну ок, пожалуй соглашусь, хотя вообще говоря рассматриваемые примеры лишены смысла, т.к. очевидно никто тут не станет объявлять аргумент как  const int&.  Такое может иметь смысл только в C++.

Возможно допустить лишь вариант с  const string&,  хотя тоже сомнительно.

 
TheXpert:

например я хочу контейнер какой-нибудь структуры встроенного типа. а у нее (тадам!!) запрещено копирование и нельзя использовать указатели.

В последних версиях МТ5 (с введением конструктора копирования и оператора присваивания по умолчанию) с копирование структур и классов больше нет ни каких проблем, кроме нескольких багов: 1, 2


для классов, структур и указательной будет проверяться наличие реализованных операторов сравнения и равенства, а так же функций Equals, Compare.

TheXpert:
как? насколько я помню sfinae в mql нету, а реализация через интерфейсы требует множественного наследования.

Используются "side-effects" работы компилятора MQL для выполнения условной компиляции в зависимости от типа объекта, переданного в шаблонную функцию.
Для проверки наличия реализованных методов у класса и структуры используется наследование с применением function overloading.
Полученные результаты "сохраняются" в виде указателей на функции.
Если определенный метод реализован то указатель будет указывать на функцию, которая принимать два объекта и вызывает соответствующий метод сравнения.


Все построено на "специфике" работы компилятора без каких-либо гарантий работоспособности при выходе новых билдов....

 
TheXpert:

может доделали, я на такое натыкался
со структурами есть еще одна проблема - из-за отсутствия ссылок и указателей нельзя изменить элемент структуры в контейнере извне.

Согласен, что основная проблема с контейнерами в MQL - невозможностью изменить элемент структуры в контейнере извне из-за отсутствия ссылок и указателей.
Если для классов и структур, в ущерб универсальности контейнеров, еще как-то можно решить проблему через наследование с реализацией класса-обертки, выполняющую роль указателя на контейнер,
то для простых типов данных int, double, string вообще ни как...
Все тупо упирается в невозможность выполнить implicit type cast от класса/структуры к простому типу.


Разработчикам:
Просьба рассмотреть возможность внедрения в MQL Type-cast operator для классов и структур.
Это позволит делать "обертки" над простыми типами, которые при использовании в контейнерах будут давать возможность изменять значение элементов контейнера извне.

Type conversions - C++ Tutorials
Type conversions - C++ Tutorials
  • www.cplusplus.com
Implicit conversions are automatically performed when a value is copied to a compatible type. For example: Here, the value of is promoted from to without the need of any explicit operator. This is known as a standard conversion. Standard conversions affect fundamental data types, and allow the conversions between numerical types ( to , to , to...
 
Основная проблема в том, что некоторые до сих пор не понимают, что ни в одном языке программирования не существует универсального оператора "сделай все за меня чтобы мне и думать не пришлось". Что бы что-то запрограммировать, надо сидеть и программировать. А если кому-то что-то не хватает, надо почаще вспоминать поговорку про танцора.
 
Vladimir Simakov:

Касательно шаблонов. В mql не поддерживается, по крайней мере пока, перегрузка шаблонных функций/методов. Сам очень грустил, когда столкнулся.

Какая-то у вас застарелая информация.
Перегрузка шаблонных функций работает без проблем:

template<typename T>
void func(T &){Print(__FUNCSIG__);}

template<typename T>
void func(T *){Print(__FUNCSIG__);}

void func(int){Print(__FUNCSIG__);}


class C{};

void OnStart(){  
   C c;
   func(c);
   func(&c);
   func(1);
}


Результат:

2019.06.10 14:56:02.166 test_plan (EURUSD,H1)   void func<C>(C&)
2019.06.10 14:56:02.166 test_plan (EURUSD,H1)   void func<C>(C*)
2019.06.10 14:56:02.166 test_plan (EURUSD,H1)   void func(int)


Может речь шла о явной спецификации специализации шаблонных функций, то да - ее нет в MQL.

 
Sergey Dzyublik:

Разработчикам:
Просьба рассмотреть возможность внедрения в MQL Type-cast operator для классов и структур.
Это позволит делать "обертки" над простыми типами, которые при использовании в контейнерах будут давать возможность изменять значение элементов контейнера извне.

dynamic_cast работает

 
Vladimir Simakov:

dynamic_cast работает

Пожалуйста, откройте ссылку и почитайте о чем идет речь (Implicit conversions with classes: Type-cast operator).
 dynamic_cast  к этому не имеет ни какого отношения:

Пример на С++:

#include <iostream>

template<typename T>
class Wrapper{
    T data;
    
public:
    int operator=(int val){
        data = val;
        return data;
    }
    
    //Type-cast operator
    operator T(){
        return data;
    }
};

int main()
{
    Wrapper<int> int_wrap;
    int_wrap = 5;
    
    int x = int_wrap;
    printf("%d", x);    // result: 5
}
 
Vladimir Simakov:

Касательно шаблонов. В mql не поддерживается, по крайней мере пока, перегрузка шаблонных функций/методов. Сам очень грустил, когда столкнулся.

перегрузка поддерживается, не поддерживается частичная и полная специализация