В макросе отсутствует несколько круглых скобок, чтобы избежать его разбиения в определенных выражениях, например, в показанном вами случае он будет заменен на:
c = (a <= b)? b : a + 1;
и, как вы можете видеть, вы вернете либо b
, либо a+1
. Это не то, что вы намеревались.
Вы должны написать макрос как
#define maxi(a, b) (((a) <= (b)) ? (b) : (a))
, чтобы избежать подобных и подобных проблем в аргументах.
Это не в любом гораздо эффективнее, чем std::max
. Компиляторы выполняют небольшие встроенные функции, и после вставки функция, использующая std::max
, будет выглядеть почти так же, как если бы была подставлена maxi
. Не будет передачи аргументов функции, будь то в регистрах или в стеке.
Кстати. Функция является шаблонной или нет, не влияет на ее рабочие характеристики. Поэтому я не знаю, почему вы упоминаете об этом в вопросе.
И, как вы можете видеть, с макросами работать намного сложнее, поэтому нет причин использовать их.
Вкл. напротив, ваш макрос будет хуже в некоторых ситуациях, например:
maxi(f(a), f(b))
, где f
- некоторая функция, будет заменять (примерно)
(f(a) <= f(b))? f(b) : f(a);
означает, что f
всегда будет оцениваться три раза, для первых двух вызовов в сравнении и один раз для выбранной ветви.
С другой стороны std::max(f(a), f(b))
оценивает f
только дважды .
Это означает, что макрос не только займет больше времени, но также может иметь непредвиденные эффекты, если вызовы функций имеют побочные эффекты.