Обратные вызовы в C++ | страница 60



Исходя из изложенного, можно сделать следующий вывод:

В системах, где предполагается интенсивное использование обратных вызовов и быстродействие является критически важным, использование универсального аргумента не является оптимальным выбором.

4.7. Проблемы, порождаемые шаблонами

4.7.1. Недостатки шаблонов

Как можно заметить из рассмотренных примеров, шаблоны являются мощным и эффективным инструментом реализации обобщенного кода. Но, как известно, не бывает ничего идеального, поэтому, конечно же, у них имеются недостатки.

Сложность разработки. При проектировании шаблонного кода операции зачастую задаются в декларативном виде, что приближает их к функциональному стилю. Использование пакетов параметров требует изощренных техник, весьма непохожих на классические приемы программирования.

Сложность понимания. Код, написанный с помощью шаблонов, гораздо труднее анализировать, чем обычный. В этом можно убедиться, просмотрев, к примеру, исходный код стандартной библиотеки STL.

Недружественность компилятора. Сообщения об ошибках, генерируемые при компиляции шаблонов, зачастую сложны и непонятны. Когда ошибка показывается где-то в недрах шаблонного кода, очень трудно бывает догадаться, возникает ли проблема из-за некорректной реализации этого кода либо из-за того, что структура данных, подставляемая в шаблон, не реализует предполагаемый интерфейс (например, требуется перегрузка некоторых операторов).

Тщательное тестирование. Шаблоны подчиняются концепции «компиляция по требованию», т. е. компилируются только те функции и методы, которые используются в коде. Поэтому, чтобы убедиться в отсутствии синтаксических и семантических ошибок, следует покрывать вызовами все функции и методы, объявленные в шаблоне. Причем желательно это делать на некотором наборе предполагаемых типов данных.

Большое время компиляции. Во-первых, компилятор осуществляет генерацию кода при каждом инстанциировании шаблона конкретным типом. Во-вторых, шаблоны для одних и тех же типов, инстанциируемые в разных участках программы, будут компилироваться заново. И, в-третьих, много времени тратится на компиляцию включаемых файлов: например, при каждом включении заголовочных файлов стандартной библиотеки все внутренние реализации шаблонов в этих файлах должны быть скомпилированы.

Склонность к разрастанию программного кода. Для каждого используемого типа будет сгенерирован отдельный код. Представим, к примеру, что мы используем шаблонную функцию с входным аргументом – числом, тип которого задается параметром шаблона. Если мы будем вызывать эту функцию с аргументами различных типов, допустим,