Новая версия платформы MetaTrader 5 build 2007: Экономический календарь, MQL5-программы в виде сервисов - страница 75

 
fxsaber:

Воспользуюсь моментом открытости. Возможно ли в MQL сделать так, чтобы функция возвращала разные типы?

Результатом этого выражения всегда является string. А нужно, чтобы был либо double, либо string, в зависимости от type.

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

 
Sergey Dzyublik:

Все можно реализовать средствами MQL.

Реализовать то можно, только пользоваться этим будет неудобно.  Если методы будут принимать только аргументы по ссылке, то во многих случаях придётся городить дополнительный огород, чтобы из r-value получить l-value.
 
Sergey Dzyublik:

Все можно реализовать средствами MQL.
Кроме части, где контейнер отвечает за результат инициализации объекта по умолчанию.
За инициализацию по умолчанию должен отвечать сам объект, а не контейнер.

Так же функция T At(int index) по сути бессмысленная и вредная, так как скрывает возможные проблемы выхода за пределы массива.
Лучше уже реализовать функцию bool TryGetValue(T &val, int index).

 
Sergey Dzyublik :

Все можно реализовать средствами MQL.
Кроме части, где контейнер отвечает за результат инициализации объекта по умолчанию.
За инициализацию по умолчанию должен отвечать сам объект, а не контейнер.

В настоящее время это не может быть реализовано в MQL.

Я не говорю о деталях реализации, таких как инициализация.

 
Alain Verleyen:

В настоящее время это не может быть реализовано в MQL.

Я не говорю о деталях реализации, таких как инициализация.

МТ5 и МТ4.
Готов реализовать универсальный контейнер (поддерживает типы данных: string, integers, pods, classes, class pointers).
На этапе компиляции проверяется тип на соответствие параметризованому контейнеру:

#property strict
#define PRINT(x) ; Print(#x, ":", string(x))


template<typename ITEM_TYPE>
class Container;


class CObject{
   int               aValue;
public:
                     CObject(void)                 {};
                     CObject(int v)                { SetValue(v); };
                     CObject(const CObject &obj)   { aValue=obj.GetValue(); };
                    ~CObject(void)                 {};
   void              SetValue(int v)               { aValue=v; };
   int               GetValue(void) const          { return(aValue); };
};

struct POD{
   int               value;
}; 
  
  
void OnStart(){
   //Integer type test
   Container<int> array_int;
   array_int.Add(1);
   
   int base_type = 4;
   array_int.Add(base_type);
   
   PRINT(array_int.At(0) == 1);
   PRINT(array_int.At(1) == 4);
   
   
   //String type test
   Container<string> array_string;
   array_string.Add("test");
   
   string string_type = "best";
   array_string.Add(string_type);
   
   PRINT(array_string.At(0) == "test");
   PRINT(array_string.At(1) == "best");
   
   
   //Class ptr type test
   Container<CObject*> array_class_ptr;
   array_class_ptr.Add(new CObject());
   
   CObject class_ptr;
   class_ptr.SetValue(5);
   array_class_ptr.Add(&class_ptr);
   
   PRINT(CheckPointer(array_class_ptr.At(0)) == POINTER_DYNAMIC);
   PRINT(array_class_ptr.At(1) == &class_ptr);
   PRINT(array_class_ptr.At(1).GetValue() == class_ptr.GetValue());
   
   
   //Class type test
   Container<CObject> array_class;
   CObject class_type;
   class_type.SetValue(55);
   array_class.Add(class_type);
   
   PRINT(&array_class.At(0) != &class_type);
   PRINT(array_class.At(0).GetValue() == class_type.GetValue());
   
   
   //Struct type test
   Container<POD> array_stuct;
   POD struct_type = {123};
   array_stuct.Add(struct_type);
   
   PRINT(array_stuct.At(0).value == struct_type.value);
   
   
   // Negative test cases
   
   struct StructA{
      uchar data;
   } a;
  
   //array_stuct.Add(a);           //Ok Compile Error 'Add' - no one of the overloads can be applied to the function call 
   //array_stuct.Add(1);           //Ok Compile Error 'operator=' - object required
   //array_stuct.Add("test");      //Ok Compile Error error 'operator=' - object required 
   //array_int.Add("test");        //Ok Compile Warning(s) implicit conversion from 'string' to 'number'  
   //array_int.Add(2234.4);        //Ok Compile Warning(s) implicit conversion from 'string' to 'number'


   class ClassB{
   
   } b;
   
   //array_class.Add(b);           //Ok Compile Error 'Add' - no one of the overloads can be applied to the function call
   //array_class.Add(1);           //Ok Compile Error 'value' - parameter conversion not allowed  
   //array_class_ptr.Add(&b);      //Ok Compile Error '=' - type mismatch    
   //array_class_ptr.Add(1);       //Ok Compile Error 'value' - parameter conversion not allowed
}
И да, контейнер еще может освобождать память динамически выделенных объектов.
 
Sergey Dzyublik :

Раз не может быть реализовано, значит должно стоить дорого, если получиться??? 
Думаю уйдет часов 2 на все. 
Будем открывать работу?

Готов реализовать:
И да, контейнер еще должен освобождать память динамически выделенных объектов .
Наверняка легко написать клиентский код, который не компилируется.
 
Ilyas :

Да, планируются

Но пока на уровне обсуждения, планируем добавить условную компиляцию в зависимости от типа T, используя которую, можно будет включать/отключать части шаблонного класса, что-то напоминающее if constexpr из С++

Так же планируем добавить различные __builtin функции (например позволяющие определить является T классом или нет), которые можно будет использовать для условной компиляции

Ницца.

Спасибо за ваш ответ.

 
Alain Verleyen:
Наверняка легко написать клиентский код, который не компилируется.

Все можно реализовать средствами MQL. 
Пример взят из рабочего кода, который проходит все проверки и вызывает delete для динамических указателей.

 
Sergey Dzyublik :

Все можно реализовать средствами MQL. 
Пример взят из рабочего кода, который проходит все проверки и вызывает delete для динамических указателей.

Очевидно, вы не поняли, в чем был мой вопрос к разработчикам MT. Ильяс это понял.

Хватит хвастаться, пожалуйста.

 
Sergey Dzyublik:

Все можно реализовать средствами MQL. 
Пример взят из рабочего кода ...

Настолько рабочего, что  

Думаю уйдет часов 2 на все. 

?

В общем, мы конечно ценим ваш оптимизм, но это не реализуемо на MQL.  Уж скоко раз уже обсуждалось в разных ветках.  Так что поберегите своё время.