Правила программирования на С и С++. Главы 7-8 - Используйте встроенные шаблоны функций вместо параметризированных макросов

ОГЛАВЛЕНИЕ

 

155. Используйте встроенные шаблоны функций вместо параметризированных макросов.

Приведенный ранее пример:

#define SQUARE(x) ((x) * (x))где: SQUARE(++x)расширяется до: ((++x)*(++x))инкрементируя x дважды. Вы не можете решить эту проблему в С, а в С++ можете. Простая встроенная функция работает вполне удовлетворительно, в таком виде: inline int square( int x ){ return x * x; }не давая побочного эффекта. Тем не менее, она допускает лишь целочисленные аргументы. Шаблон функции, который расширяется во множество перегруженных встроенных функций, является более общим решением: template ?class type>

inline type square( type x ){ return x * x; }

К несчастью, это срабатывает только в простых ситуациях. Следующий шаблон не может обработать вызов max(10, 10L), потому что не совпадают типы аргументов: template ?class type>

inline type max( type x, type y ){ return (x > y) ? x : y; }

Для обработки max(10, 10L) вы должны использовать прототип, чтобы принудить к расширению по тому варианту max(), который может выполнить данную работу: long max( long, long );Прототип вызывает расширение шаблона. Компилятор с легкостью преобразует аргумент типа int в long, даже если ему не нужно делать это преобразование для расширения шаблона.

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