It was a poor choice on the part of the author to use the macro-looking MAX() in his example. There is in fact a standard max() function in the <algorithm> header that does not suffer from silly macro-expansion problems:
template<class T>
const T& max(const T& a, const T& b) {
return a < b ? b : a;
}
template<class T, class Predicate>
const T& max(const T& a, const T& b, Predicate p) {
return p(a, b) ? b : a;
}
And your definition of MAX() is wrong, not just because of multiple evaluation of the arguments. The “conventionally wrong” MAX() would be this: #define MAX(a, b) ((a) < (b) ? (b) : (a))