Ошибка компилятора - неправильная перегрузка методов

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexey Navoykov
4570
Alexey Navoykov  

Следующий код демонстрирует неправильный выбор шаблонного метода компилятором.  Переходит в метод _C::f(), пытаясь вызвать A<B>::X(),  хотя в классе C определена более подходящая сигнатура A<T>, это явно точнее чем T.  Кроме того, класс C имеет приоритет при выборе метода.  А в родительский класс должно попадать только то, что не нашло соответствий в основном классе и требует приведения, насколько я знаю.

В с++ всё работает нормально.

template<typename T>
struct A
{
  int _a;
  void a() { };
};

struct B
{ 
};

struct _C
{
  template<typename T>
  static void f(T& t) { t.X(); }  //'X' - member function not defined
};

struct C : _C
{
  template<typename T>
  static void f(A<T>& a) { a.a(); };
};

void Main()
{ 
  A<B> a;
  C::f(a);
}
TheXpert
18271
TheXpert  
Alexey Navoykov:

Кроме того, класс C имеет приоритет при выборе метода.

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

Alexey Navoykov
4570
Alexey Navoykov  
TheXpert:

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

Поменял - появилась ошибка ('X' : is not a member of 'A<T>').  Компилятор VS2010, хотя думаю везде так
TheXpert
18271
TheXpert  
Alexey Navoykov:
Поменял - появилась ошибка.  Компилятор VS2010

да, ошибся, приоритет по классам влияет

но если обе функции в одном классе, компилится

получается сразу две ошибки?

Alexey Navoykov
4570
Alexey Navoykov  
TheXpert:

получается сразу две ошибки?

А ***знает, скоко их, но то что шаблонный класс не уважают - это факт )
fxsaber
16731
fxsaber  
template functions overloading is not supported yet
A100
2094
A100  
TheXpert:
получается сразу две ошибки?

Нет... здесь нет ошибок

A100
2094
A100  

Alexey Navoykov:
А в родительский класс должно попадать только то, что не нашло соответствий в основном классе и требует приведения, насколько я знаю.

В с++ всё работает нормально.

В С++ работает потому что там действует фундаментальный принцип: изменения в базовом классе не должны влиять на поведение производного. В MQL этот принцип не работает по принципиальным соображениям (в родительский класс попадает все, кроме полного совпадения - в данном случае кроме A<B>&) .

Ремарка: перефразируя https://www.mql5.com/ru/forum/278274/page3#comment_8641454: назовите мне компилятор (кроме MQL) в котором этот принцип не действует

Баг компилятора: cannot convert from const pointer to nonconst pointer
Баг компилятора: cannot convert from const pointer to nonconst pointer
  • 2018.09.10
  • www.mql5.com
Билд 1881. Баг компилятора: путает константность указателя с константностью объекта, на который он ссылается. Здесь переменная a - это не константа...
TheXpert
18271
TheXpert  
A100:

Нет... здесь нет ошибок

тогда объясните.

A100
2094
A100  
TheXpert:

тогда объясните.

А этого недостаточно? Могу добавить что C++ в силу указанного принципа даже ничего не хочет знать про базовый класс если подходящий метод есть в производном (и до ошибки не доходит). А если поменять местами _C::f и C::f то поведение компиляторов одинаково... т.е. оба находят ошибку будучи еще в производном классе
Алексей Тарабанов
9739
Алексей Тарабанов  
TheXpert:

тогда объясните.

Вроде, уже объяснил. Если в с++ "что родилось, то уже родилось", то в MQL мутация генов родителя влечет соответствующее изменение генов уже рожденных детей. 

Никак не соответствует генетике, но вполне имеет право на жизнь и даже интересненько... 

Если я правильно понял исходный пост. 

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий