Обратные вызовы в C++ | страница 61
4.7.2. Ограничения шаблонов
В общем-то, рассмотренные недостатки не так уж значительны, и преимуществ у шаблонов значительно больше. Тем не менее, они имеют фундаментальное ограничение, вытекающие из их внутренней природы: шаблоны не создают предварительно откомпилированного кода. По большому счету шаблон представляет собой не сам код, а правила для генерации кода. Пока шаблон не инстанциирован, его код отсутствует; после инстанциирования последний генерируется только для тех методов и функций, которые были вызваны. Из указанного ограничения вытекают следующие выводы.
Интерфейс шаблона не может быть отделен от реализации. И объявление шаблона, и его реализация должны находиться в одной области видимости (модель включения). Таким образом, при изменениях в реализации шаблона все компоненты, которые его используют, должны быть перекомпилированы.
Шаблоны не могут поставляться в виде статических или динамических библиотек, они должны поставляться только в виде исходного кода. Никакие сторонние приложения (за исключением компиляторов C++, разумеется) не могут использовать функциональность, реализованную на базе шаблонов.
По вышеуказанным причинам,29
С помощью шаблонов невозможно реализовать интерфейсы API.
4.8. Итоги
Шаблоны обеспечивают параметрический полиморфизм, что позволяет писать обобщенный код, реализующий заданную функциональность без привязки к типам данных.
Инициатор для синхронных вызовов реализуется с помощью шаблонов функций, асинхронных – с помощью шаблонов классов.
В реализации шаблона инициатора тип объекта вызова задается параметром. Поскольку разные типы объектов требуют различное число параметров и используют неодинаковый синтаксис, для сохранения единой реализации используется преобразование вызовов.
Функциям, реализующим алгоритмы, зачастую требуются различные операции над данными. Поскольку в обобщенном коде типы данных заранее не известны, для реализации операций используются предикаты.
В асинхронных вызовах для каждого типа аргумента приходится инстанциировать соответствующий инициатор. Использование универсального аргумента позволяет реализовать единый класс для любых типов аргументов, однако в некоторых случаях это может привести к падению производительности.