Блок кода в макросе препроцессора C++ не работает без фигурных скобок
Частично работает следующее #define
:
#define OUT(x)
if(x > 0) cout << "Hello ";
if(x > 1) cout << x+1
OUT(1) << "message"; // OK
if(0) {
OUT(1) << "message"; // OK, nothing printed
}
if(0)
OUT(1) << "message"; // NO, printed anyway
Я понимаю, почему это не работает (if(0)
относится только к if(x > 0)
).Я не могу найти способ заставить его работать. Учтите, что я не могу поставить фигурные скобки в define, иначе мне не разрешат использовать оператор вставки.
2 ответа:
Обновлено для печати "Hello"
Это можно сделать так (о уродство!):
#define OUT(x) if((x > 0 ? cout << "Hello " : cout), x > 1) cout << x+1
Это "стандартный" трюк оператора запятой, который позволяет вычислять дополнительные выражения в пределах условного
В этом случае добавляется одно выражение: тернарный оператор, который вычисляет исходное условиеif
, не затрагивая ветвь, взятую в конце.x > 0
. Выражение (не утверждение, но это ограничение здесь не имеет значения), которое производит желаемую сторону эффект помещается в "истинную" ветвь Троицы. Не имеет никакого значения, к чему приводит" ложная " ветвь, если она имеет тот же тип, что и результат "истинной" ветви (или может быть неявно преобразована в него).Здесь "истинная" ветвь возвращает
ostream&
, поэтому самый простой способ-вернутьсяcout
из "ложной" ветви и назвать ее днем.Ответ на первоначальный вопрос
В первоначально опубликованном случае (с
x
иy
) макрос будет быть#define OUT(x) if((x > 0 ? y = x : 0), x > 1) cout << x+1
, который для данного конкретного случая может быть также записан как
#define OUT(x) if((y = x > 0 ? x : y), x > 1) cout << x+1