Новая версия платформы MetaTrader 5 build 2085: Интеграция с Python и массовые улучшения в тестере стратегий - страница 47

 
я вернулся)
 
Как сделать, чтобы этот код компилировался без проблем?
class A1
{
public:
  void Test( bool ) {}
};

class A2
{
public:
  void Test( bool ) {}
};

class B1 : public A1
{
public:
  void Test() {}
};

class B2 : public A2
{
public:
  void Test() {}
};

template <typename T>
void Func( T &obj )
{
  obj.Test(true); // deprecated behavior, hidden method calling will be disabled in a future MQL compiler version
}

void OnStart()
{
  B1 b1;
  B2 b2;
  
  Func(b1);
  Func(b2);
}

Неужели в C++ такая удобная конструкция с шаблоном не прокатывает?

 
В Терминале ничего не запускалось. В журнале такое
2019.09.06 06:02:16.391 Network '70002134': scanning network for access points
2019.09.06 06:02:23.371 Virtual Hosting failed to get list of virtual hosts (www.mql5.com:443 send request failed [12002])
2019.09.06 06:02:32.900 Network '70002134': scanning network finished
2019.09.06 06:02:45.574 MQL5.chats      socket read(available) failed, size: 524288
 
fxsaber:
Как сделать, чтобы этот код компилировался без проблем? 

По всей видимости теперь только если уговорить Ильяса отменить данное решение... )   Мне лично тоже неясны мотивы этого запрета.  Занудства ради? Кому от таких конструкций было плохо?  Какие там могут быть проблемы?  Это не же не перекрытие метода, а просто перегрузка с совершенно другой сигнатурой.   Вызвать другой метод по ошибке невозможно.

Пусть даже в С++ по какой-то причине это запрещено,  но там есть выбор альтернативных решений.  Например исходный тип может унаследовать интерфейс с соответствующим методом, тогда вместо шаблонного типа в функцию будет передаваться интерфейсный тип. И это будет правильно.  А в MQL нет множественных интерфейсов, классы приходится наследовать непосредственно друг от друга.   Получается, что и без того ограниченные возможности MQL ещё больше урезаются, лишая простора для манёвра.

 
fxsaber

Кстати посмотрел внимательнее, в вашем конкретном случае вполне можно обойтись интерфейсом (и не можно, а нужно)

class A
{
 public:
  virtual void Test( bool ) = 0;
};

class A1 : public A
{
public:
  void Test( bool ) {}
};

class A2 : public A
{
public:
  void Test( bool ) {}
};

class B1 : public A1
{
public:
  void Test() {}
};

class B2 : public A2
{
public:
  void Test() {}
};

void Func(A &obj)
{
  obj.Test(true);
}
 
Andrey Barinov:

В билде 2136 сломали typename()

Прошу починить обратно.


Спасибо, внёс исправление.
 
Alexey Navoykov:

Кстати посмотрел внимательнее, в вашем конкретном случае вполне можно обойтись интерфейсом (и не можно, а нужно)

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

 
fxsaber:

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

К сожалению, пока не добавили инструкцию using, придётся заводить в производном классе нужную перегрузку из которой вызвать родительский метод

class A2 : public A
{
public:
  void Test( bool ) {}
};

class B2 : public A2
{
public:
  void Test(bool x) { A2::Test(x); }
  void Test() {}
};

На быстродействии это не скажется.

 
Ilyas:

придётся заводить в производном классе нужную перегрузку из которой вызвать родительский метод

Такое решение не сильно отличается от интерфейсного решения, к сожалению.

Придется править написанные другими авторами классы.

 
fxsaber:

Такое решение не сильно отличается от интерфейсного решения, к сожалению.

Придется править написанные другими авторами классы.

Сделайте конструкцию более высокоуровневую:

class A2 : public A
{
public:
  void Test( bool ) {}
};

class B2 : public A2
{
public:
  void Test() {}
};

class C2 : public B2
{
public:
  void Test(bool x) { A2::Test(x); }
  void Test() { B2::Test(); }
};