Ошибки, баги, вопросы - страница 2652

Какие различия для компилятора у следующих строк?
Print("123" "456");
Print("123" + "456");
Print("123", "456");
MQL понемногу деморализует:
#ifdef __cplusplus
    #include<iostream>
    #include<stdio.h>
#endif

class input_iterator_tag  {};
class output_iterator_tag {};
class forward_iterator_tag       : public input_iterator_tag         {};
class bidirectional_iterator_tag : public forward_iterator_tag       {};
class random_access_iterator_tag : public bidirectional_iterator_tag {};

struct MyIterator{
public:
   int index;
   class iterator_category : public random_access_iterator_tag{};
   
   MyIterator(int __index = 0):index(__index){}
   
   bool operator!=(MyIterator &it){
      return index != it.index;
   }
   
   int operator-(MyIterator &it){
      return index - it.index;
   };
   
   MyIterator operator++(){
      index+=1;
#ifdef __cplusplus
      return *this;
#else
      return this;
#endif 
   } 
};

template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, input_iterator_tag*){
    int __r=0;
    for (; __first != __last; ++__first)
        ++__r;
    return __r;
}

template <typename _RandIter>
int __distance(_RandIter &__first, _RandIter &__last, forward_iterator_tag*){
    return __last - __first;
}


//+------------------------------------------------------------------+
//| MQL realization                                                  |
//+------------------------------------------------------------------+
#ifdef __MQL5__
// Bypass the bug (https://www.mql5.com/ru/forum/1111/page2648#comment_15015191)
template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, forward_iterator_tag* __category){
   return __distance(__first, __last, (input_iterator_tag*) __category);
};

template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, random_access_iterator_tag* __category){
   return __distance(__first, __last, (bidirectional_iterator_tag*) __category);
};


// Bypass Compilation ERROR: '_InputIter' - struct undefined    
template<typename T>
class GetStructType{
public:
   struct type : public T{};
};


template <typename _InputIter>
int distance_mql(_InputIter &__first, _InputIter &__last){
   //_InputIter::iterator_category category;                      //Compilation ERROR: '_InputIter' - struct undefined  
   GetStructType<_InputIter>::type::iterator_category category;
   GetStructType<_InputIter>::type::iterator_category* ptr = &category;
   
   // Bypass the bug (https://www.mql5.com/ru/forum/1111/page2648#comment_15015191)
   random_access_iterator_tag* ptr_ra = dynamic_cast<random_access_iterator_tag*>(ptr);
   if(ptr_ra != NULL){
      return __distance(__first, __last, ptr_ra);
   };
   
   bidirectional_iterator_tag* ptr_bd = dynamic_cast<bidirectional_iterator_tag*>(ptr);
   if(ptr_bd != NULL){
      return __distance(__first, __last, ptr_bd);
   };
   
   forward_iterator_tag* ptr_fw = dynamic_cast<forward_iterator_tag*>(ptr);
   if(ptr_fw != NULL){
      return __distance(__first, __last, ptr_fw);
   };
   
   input_iterator_tag* ptr_in = dynamic_cast<input_iterator_tag*>(ptr);
   if(ptr_in != NULL){
      return __distance(__first, __last, ptr_in);
   };
   
   //TODO RAISE EXCEPTION
   return -1;
}

void OnStart(){
   MyIterator it1(1);
   MyIterator it2(5);
   printf("result:%d", distance_mql(it1, it2));            
}
#endif 


//+------------------------------------------------------------------+
//|  C++ realization, online: https://onlinegdb.com/S1tcVt9XU 	     |
//+------------------------------------------------------------------+
#ifdef __cplusplus
template <typename _InputIter>
int distance_cplusplus(_InputIter &__first, _InputIter &__last){
    return __distance(__first, __last, (typename _InputIter::iterator_category*)(NULL));
}

int main(){
   MyIterator it1(1);
   MyIterator it2(5);
   printf("result:%d", distance_cplusplus(it1, it2)); 
   
   return 0;
}
#endif 

Краткая суть бага:
Когда есть наследование классов A <= B <= C <= D
и реализованы две overloading функции, например одна c параметра А*, а вторая с B*,
то передача в такую функцию объекта C* или D* в MQL вызывает ошибку компиляции "ambiguous call to overloaded function".

Вопрос: есть ли более вменяемый обход этого идиотского бага, чем представленный выше?
[Удален]
Пошли очередные простыни "Почему MQL != C++"...
Сергей Таболин:
Пошли очередные простыни "Почему MQL != C++"...

Зачем что-то комментировать, если вы ни как не разобрались в сути вопроса?

[Удален]
Sergey Dzyublik:

Зачем что-то комментировать, если вы ни как не разобрались в сути вопроса?

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

И затем, что разница в языках ни к ошибкам, ни к багам не относится!

MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
  • 2019.08.02
  • www.mql5.com
Общую тему багов и вопросов просто уже снасильничали такими разборками. Предложил открыть специализированную ветку, никто не чешется...
Sergey Dzyublik:
MQL понемногу деморализует:

Краткая суть бага:
Когда есть наследование классов A <= B <= C <= D
и реализованы две функции, например одна для параметра А*, вторая для B*,
то передача в такую функцию объекта C* или D* в MQL вызывает ошибку компиляции "ambiguous call to overloaded function".

Вопрос: есть ли более вменяемый обход этого идиотского бага, чем представленный выше?

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

Vladimir Simakov:

Ну не перекладывается STL один в один. Тут надо с большим оглядом на специфику. 

Вы путаете теплое с мягким.
Вопрос не в STL. Там сам разберусь... (если у кого-то не перекладывается, это не означает, что это не возможно в принципе сделать)

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

Предложенный вами способ был реализован ранее и так же упирается в этот же баг: https://www.mql5.com/ru/forum/1111/page2648#comment_15015191


Баг в приоритетах вызова перезагруженных функций, когда для параметра указателя/класса выполняется implicit type conversion.
В С++ - все ОК, а в MQL - ошибка компиляции "ambiguous call to overloaded function"
Выше предложен один из вариантов обхода, но он большой и не удобный, и использовать его еще для десятка таких же функций желания ну ни как нет.
Возможно есть что-то по проще???

Макросы делают свое дело, удалось полотно сократить к виду (полная версия в файле вложения):
//+------------------------------------------------------------------+
//|  MQL realization                                                 |
//+------------------------------------------------------------------+
#ifdef __MQL5__
   template <typename _InputIter>
   CREATE_MISSED_ITERATOR_FUNCTION_FW_P2(int, distance, _InputIter&, _InputIter&);
   
   template <typename _InputIter>
   CREATE_MISSED_ITERATOR_FUNCTION_RA_P2(int, distance, _InputIter&, _InputIter&);

   template <typename _InputIter>
   CREATE_MAIN_ITERATOR_FUNCTION_P2(int, distance, _InputIter&, _InputIter&, _InputIter);
   
   void OnStart(){
      MyIterator it1(1);
      MyIterator it2(5);
      printf("result:%d", distance(it1, it2));            
   }
#endif 

Разработчики, подскажите пожалуйста, планируется ли исправление бага или это архитектурно невозможно?
Файлы:
Баг МТ5(build 2323),
внутри шаблонной функции, переданный указатель в рамках операции явного приведения типа ведет себя как класс, вызывая, соответственно, ошибку компиляции:
#define PRINT(x) ; Print(#x, ":", string(x))

template<typename T>
class ClassWrapper{
public:
   T data;
};

class ClassA{};
class ClassB : public ClassA{};


template<typename T, typename TT>
void func(const T &_wrapper, const TT &value){
   T wrapper = _wrapper;   
   
   PRINT(typename(wrapper.data));         // Ok: ClassA*
   PRINT(typename(value));                // Ok: ClassA*
   PRINT(typename(TT));                   // Ok: ClassA*
   
   //wrapper.data = (TT)(value);          // Compiler Error: 'value' - object required  
   //wrapper.data = (TT)(wrapper.data);   // Compiler Error: 'data' - object required   
   
   ClassB b;
   PRINT(typename((TT)(b)));              // Result: ClassA. During explicit type conversion, TT is "ClassA" instead of "ClassA*"
};


void OnStart(){
   ClassWrapper<ClassA*> a_ptr_wrapper;
   
   ClassA a;
   const ClassA* a_ptr = &a;
   func(a_ptr_wrapper, a_ptr);
};

Туплю, не могу решить простую задачу. Нужно при следующих настройках запуска советника понять, что торговля запрещена.


Такая проверка не прокатывает.

int OnInit()
{
  Alert(AccountInfoInteger(ACCOUNT_TRADE_EXPERT) &&
        AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) &&
        TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)); // true
        
  return(INIT_FAILED);
}


OrderCheck - из пушки по воробьям. Прошу подсказать.