Я думал, что то же самое с обычными (не шаблонными) функциями.
Нет. Большинство компиляторов при компиляции (не static
) функции просто генерируют объектный код для этой функции (который они могут позже изменить при оптимизации всей программы, но это делают не все компиляторы). Это не сделано для шаблонных функций, так как (а) они могут не содержать достаточно информации, чтобы выдать весь объектный код, и (б) они могут принять бесконечное число возможных значений для своих аргументов шаблона, поэтому компилятору придется компилировать бесконечное количество функций.
Рассмотрим
template <typename T>
T add1(T x)
{
return x + 1;
}
Эта шаблонная функция может быть применена к любому типу T
, для которого определен operator+
и может принимать аргумент int
, и, поскольку вы можете создавать такие типы самостоятельно с перегрузкой операторов, их потенциально бесконечное число .
Вместо этого, во время компиляции, когда компилятор встречает вызов шаблона
функция, она копирует функцию шаблона и заменяет тип шаблона
параметры с актуальными типами
... но компоновщик заметит, что если вы используете add1
для одного и того же типа T
(скажем, float
) в нескольких модулях, скомпилированный объектный код будет одинаковым в каждом случае, и он удалит дубликаты.