Почему C++ не поддерживает параметрический полиморфизм?

Согласно странице википедии для параметрического полиморфизма:

Некоторые реализации полиморфизма типов внешне похожи на параметрический полиморфизм, но также вводят специальные аспекты. Одним из примеров является специализация шаблонов C++.

Вопрос. Почему говорят, что C++ реализует только что-то внешне похожее на параметризованный полиморфизм? В частности, разве шаблоны не являются примером полного параметрического полиморфизма?


person George    schedule 29.04.2016    source источник
comment
Независимо от ответа на этот вопрос, эта страница в Википедии нуждается в большой любви...   -  person Barry    schedule 30.04.2016
comment
Эта вики-страница исходит из теоретической точки зрения - строгой математической спецификации теории типов, и, таким образом, термин параметрический полиморфизм имеет строгое определение. Шаблоны С++ более... гибкие... чем любая такая теория могла бы/обеспечила бы. А так... пожалуй, полезнее! Конечно, намного интереснее! Во всяком случае, я всегда слышал, что шаблоны C++ описываются как специальный полиморфизм.   -  person davidbak    schedule 30.04.2016


Ответы (2)


Почему говорят, что С++ реализует только что-то внешне похожее на параметризованный полиморфизм? В частности, разве шаблоны не являются примером полного параметрического полиморфизма?

Шаблонные функции в C++ работают на основе "подстановки" параметра. По сути, это означает, что компилятор генерирует еще одну версию функции, в которой аргументы шаблона жестко закодированы в функцию.

Предположим, у вас есть это на С++:

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int i = add(2, 3);
    double d = add(2.7, 3.8);
    return i + (int)d;
}

Во время компиляции это приведет к двум функциям: int add(int a, int b) { return a + b; } и double add(double a, double b) { return a + b; } Одна функция будет обрабатывать ТОЛЬКО целые числа, а другая будет обрабатывать ТОЛЬКО двойные числа. Отсутствие полиморфизма.

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

«Но почему это не параметрический полиморфизм?» — спросите вы?

Вам нужен полный исходный код функции «добавить», чтобы вызвать ее с вашим собственным вариантом чего-то, что перегружает двоичный оператор «+»! – Это деталь, которая имеет значение.

Если бы C++ имел надлежащий параметрический полиморфизм, как, например, C#, ваша окончательная скомпилированная реализация «добавить» содержала бы достаточно логики, чтобы определить во время выполнения, какой будет перегрузка «+» для любого заданного параметра, приемлемого для «добавления». И вам не понадобится исходный код этой функции, чтобы вызывать ее с помощью новых изобретенных вами типов.

Что это означает на самом деле?

Но не понимайте это так, будто C++ менее мощный или C# более мощный. Это просто одна из многих особенностей языка.

Если у вас есть полный исходный код для ваших шаблонных функций, то семантика C++ намного лучше. Если в вашем распоряжении есть только статическая или динамическая библиотека, лучше использовать параметрическую полиморфную реализацию (например, C#).

person Zuu    schedule 30.04.2016
comment
Я не согласен. Это все-таки полиморфизм: у него то же имя, но другая форма внутри. Это перевод полиморфизма. Делается ли это во время компиляции или во время выполнения, не имеет значения. - person Palo; 21.10.2020

Статья, на которую вы ссылаетесь, объясняет это. Сам текст, который вы процитировали, на самом деле дает один пример того, что отличает шаблоны С++ от чистого параметрического полиморфизма: специализация шаблонов С++.

Он продолжает эту тему:

Согласно Кристоферу Стрейчи,[2] параметрический полиморфизм можно противопоставить специальному полиморфизму, в котором одна полиморфная функция может иметь несколько различных и потенциально разнородных реализаций в зависимости от типа аргумента (аргументов), к которому она применяется. Таким образом, специальный полиморфизм обычно может поддерживать только ограниченное число таких различных типов, поскольку для каждого типа должна быть предусмотрена отдельная реализация.

Таким образом, как описано, шаблоны C++ близки к параметрическому полиморфизму, но не являются им в точности.

person Lightness Races in Orbit    schedule 29.04.2016