Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
А почему шаблоны должны отличаться? Если в базовом классе есть лучшая функция то выбирается она... а специализация лучше шаблона по определению (тот же C++ при наличии шаблона и специализации выбирает специализацию). Если шаблон в производном будет лучше специализации в базовом то при одновременном сохранении этого правила будет полная неразбериха
В данном примере лучшая функция (специализация) находится в производном классе. Но она не выбирается.
Если шаблон в производном будет лучше специализации в базовом то при одновременном сохранении этого правила будет полная неразбериха
Я уже писал, если в С++ поменять местами, то он в любом случае выбирает ту, что в производном классе. Потому что это шаблон, а не кастинг. Специализация может иметь преимущество только если она находится в том же классе или позже.
p.s. Рассуждаю только из того, что вижу. Если у вас есть ссылка на чёткие правила, то будет лучше
Alexey Navoykov:
Я уже писал, если в С++ поменять местами, то он в любом случае выбирает ту, что в производном классе. Потому что это шаблон, а не кастинг. Специализация может иметь преимущество только если она находится в том же классе или позже.
С++ выбирает ту что в производном и в случае шаблона и в случае кастинга. Было бы странно если бы MQL руководствовался в случае шаблона одним принципом, а в случае кастинга противоположным
Ок, ну смотрите. Вот примерно ваш случай:
В методе A::f() программист заложился на один тип. В методе B::f() - на другой. И неизвестно, какой именно тип имел ввиду пользователь, и какие последствия будут от приведения типа.
А вот в случае шаблона
в обоих функциях программист заложился на тип X<int> , просто в одном случае это указано более чётко, а в другом менее. Но в обоих случаях это точно совпадает с типом принимаемого значения. Информации о типе не теряется. Так с какой стати нужно идти в родительский класс? Данный случай эквивалентен, как если бы в обоих классах была перегружена функция с абсолютно одинаковой сигнатурой: void f(X<int>&)
Как минимум не логично предъявлять Разработчикам ошибку без правильного кода
не хотел без компилятора что-то писать, у меня дома нет 5ки. Поэтому отложил до утра. Вот код:
Мы видим 1 в обоих случаях. По логике должно быть или 1 2 или 2 2.
Итого получается что
1. у специализаций базового и наследника одинаковый приоритет
2. выбирается менее узкая специализация, что в любом случае неправильно.
будем надеяться что когда перегрузка шаблонных функций будет реализована, (2) починится автоматом.
Ок, ну смотрите. Вот примерно ваш случай:
В методе A::f() программист заложился на один тип. В методе B::f() - на другой. И неизвестно, какой именно тип имел ввиду пользователь, и какие последствия будут от приведения типа.
А вот в случае шаблона
в обоих функциях программист заложился на тип X<int> , просто в одном случае это указано более чётко, а в другом менее. Но в обоих случаях это точно совпадает с типом принимаемого значения. Информации о типе не теряется. Так с какой стати нужно идти в родительский класс? Данный случай эквивалентен, как если бы в обоих классах была перегружена функция с абсолютно одинаковой сигнатурой: void f(X<int>&)
Так я и не понимаю: если f(int) может вызываться в Вашем примере вместо f(double), то почему f(X<T>&) не может вызываться вместо f(T&). И наоборот: если f(int) не может вызываться вместо f(double), то почему f(X<T>&) может вызываться вместо f(T&). Почему разработчик и пользовать класса в случае кастинга могут иметь ввиду разное, а в случае шаблонов непременно будут иметь ввиду одно и тоже. Да... тип сохраняется... но он может вообще в дальнейшем не использоваться (как и значение)... главное что тело методов разное а значит может быть разный результат.
Принцип стабильности он либо соблюдается... и тогда везде единый порядок... либо не соблюдается... и тогда неразбериха: в случае кастинга один порядок... в случае шаблонов другой... в случае константности третий... (константность ещё не затрагивали - а там в MQL другой порядок) и возникает необходимость все эти порядки учитывать
Так я и не понимаю: если f(int) может вызываться в Вашем примере вместо f(double), то почему f(X<T>&) не может вызываться вместо f(T&). И наоборот
Потому что f(double) - это не точная сигнатура, требующая приведения. А шаблон f (T&) раскрывается в точную сигнатуру. Поэтому я не вижу противоречия. Производится поиск от производного класса к родительскому. И как только находится точная сигнатура, то используем её.
Да... тип сохраняется... но он может вообще в дальнейшем не использоваться (как и значение)... главное что тело методов разное а значит может быть разный результат.
Очевидно программист должен позаботиться об этом, коль он взял на себя ответственность принимать любой тип переменной.
Принцип стабильности он либо соблюдается... и тогда везде единый порядок... либо не соблюдается... и тогда неразбериха
Возможно и так... Но я пока не могу себе представить неразбериху, т.к. ощущаю разницу между шаблонным типом и приведением типа.
Но по большому счёту, надо действительно менять весь порядок, включая и перегрузку обычных методов, чтоб было как в С++. Я вот сначала, прочитав их аргументы про "палку о двух концах", посчитал что там действительно нет однозначного решения. Но подумав, понял что эти концы совершенно не равноценны, из двух зол надо выбирать наименьшее. Создатель производного класса всё знает о методах родительского, поэтому производя перегрузку он может (и должен) учесть их. А родитель ничего не знает о наследниках.
// Впрочем ладно, теперь уже вряд что-то станут менять в этом плане.