Ответ 1
Почему С++ говорит, что он реализует нечто, внешне похожее на параметризованный полиморфизм? В частности, не являются ли шаблоны примером полного параметрического полиморфизма?
Шаблонные функции в С++ работают на основе "подстановки" параметра. Что по существу означает, что компилятор генерирует еще одну версию функции, в которой аргументы шаблона жестко закодированы в функции.
Предположим, что у вас есть это в С++:
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; }
Одна функция будет ТОЛЬКО обрабатывать ints, а другая будет ТОЛЬКО обрабатывать удвоения. Полиморфизм отсутствует.
Итак, вы в итоге получаете столько реализаций, сколько количество вариантов аргументов.
" Но почему это не параметрический полиморфизм?" вы можете спросить?
Вам нужен полный исходный код функции "добавить", чтобы вызвать его с вашим собственным изменением того, что перегружает двоичный оператор "+"! - Это детали, которые делают разницу.
Если у С++ был правильный параметрический полиморфизм, например С#, ваша окончательная скомпилированная реализация "add" будет содержать достаточно логики, чтобы во время выполнения определить, что "+" перегрузка будет для любого заданного параметра, приемлемого для "добавления". И вам не нужен исходный код для этой функции, чтобы называть его новыми типами, которые вы изобрели.
Что это означает в действительности?
Но не понимайте это, как если бы С++ был менее мощным или С# был более мощным. Это просто одна из многих особенностей языка.
Если у вас есть полный источник, доступный для ваших шаблонных функций, то семантика С++ намного выше. Если в вашем распоряжении только статическая или динамическая библиотека, то параметрическая полиморфная реализация (например, С#) превосходит.