Здравствуйте, samius, Вы писали:
_>>Если же говорить о классическом применение шаблонов (типа контейнеров STL), то для программиста это безусловно является параметрическим полиморфизмом. Хотя бы потому, что программист пишет ровно одну версию кода для всех типов.
S>Этот тезис уже не касается стандартной equal_to, т.к. одну версию для всех типов он не держит. Без специализации equal_to работает лишь для ограниченного количества типов и всегда найдется тип, для которого equal_to не работает "из коробки".
Стандартная equal_to работает для всех типов, для которых определён оператор равенства. Точно так же как и какой-нибудь vector<T> работает не для всех типов, а только для имеющих (как минимум) конструктор и оператор перемещения. Так что не пойму где ты тут увидел разницу с контейнерами STL.
_>>А то, что компилятор там потом из соображений оптимизации может размножать эти версии кода, это уже дело десятое и на структуру кода не влияет. Это кстати можно легко увидеть с помощью простейшего мысленного эксперимента: если допустим поменять компилятор C++ так, чтобы он реализовывал шаблоны например по механизму параметрического полиморфизма Хаскеля, то весь классический шаблонный код продолжит спокойно работать без всяких изменений (ну разве что медленным станет, как Хаскель).
S>Мысленный эксперимент в баню, мы ведь говорим о конкретном языке C++, а не о сферовакуумном H++.
S>Я предлагаю обратиться к источнику классификации:
Ууу) Ты всё же решился свернуть на эту холиварную тему. Вопрос о сути шаблонов C++ уже давно является известной темой для споров. И на этом форуме и на других известных. Повторять все эти потоки флейма нет никакого желания — это всё можно найти на форуме самостоятельно. Так что просто выскажу своё итоговое мнение по данному вопросу, в сравнение с тем же Хаскелем:
У C++ есть параметрический полиморфизм на уровне исходного кода и нет никакого полиморфизма (ну кроме банальных виртуальных функций) на уровне машинного кода (и поэтому он работает быстро).
У Хаскеля есть параметрический полиморфизм на уровне исходного кода и на уровне машинного кода (и поэтому он работает медленно).
Основная цель всего этого механизма в том, чтобы облегчить работу программиста, позволив ему писать один код для всех случаев. Шаблоны из C++ это полностью реализуют. А с учётом ещё и вопроса производительности данное решение выглядит на голову лучше всех остальных реализаций. Ценой же этого (ну никогда не бывает идеала и у всех мощных технологий есть обратная сторона) являются большие сложности с введением в язык модулей.
_>>Если очень хочется увидеть подобный компаратор, не являющийся просто обёрткой вокруг какого-то одного оператора, а привносящий какую-то логику, то есть варианты гораздо проще. Например так:
_>>_>>bool operator()(const T &lhs, const T &rhs) const
_>>{
_>> return lhs.compare(rhs)==0;
_>>}
_>>
S>И что, это работает для всех типов, или только для тех, у которых определен инстанс метод compare?
Для всех типов, у которых определена функция-член compare.
_>>Но на самом деле все эти дополнительные доказательства уже не нужны, т.к. уже та самая простейшая обёртка является очевидным представителем параметрического полиморфизма — работает для многих типов и при этом в исходных кодах ровно одна реализация.
S>Что значит "для многих типов"? Формально нужна работа для всех типов.
С чего бы это? Откуда такое бредовое требование? Да ещё и формальное... )))
Т.е. если я напишу на Хаскеле функцию f вида "f a = xrmbrm a", то она по твоему обязательно будет работать для всех типов? ))) Или быть может в Хаскеле тоже нет параметрического полиморфизма? )))
S>И одна реализация для всех, так, что бы даже компилятор и рантайм не нуждались в указании нужной реализции.
Ну это уже как раз тот самый спорный вопрос (см. выше).
_>>И так, подводя итоги:
_>>1. equal_to — компаратор.
_>>2. работает с разными типами — полиморфный.
_>>3. имеет одну реализацию для всех типов — параметрический.
S>пожалуй, я найду тип, для которого стандартная реализация не работает. Точнее, мешает скомпилироваать проект.
И? ) Это как-то влияет на аргументацию? )