Правила программирования на Си и Си++


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


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

#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

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



Содержание раздела