C++预处理器宏中的代码块在没有大括号的情况下不起作用

Pie*_*tro 2 c++ insertion operator-keyword c-preprocessor

以下#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
Run Code Online (Sandbox Code Playgroud)

我理解为什么它不起作用(if(0)仅适用于if(x > 0)).
我找不到让它发挥作用的方法.考虑到我不能在定义中添加大括号,否则我将不允许使用插入运算符.

Jon*_*Jon 5

更新后打印"你好"

它可以这样做(哦,丑陋!):

#define OUT(x) if((x > 0 ? cout << "Hello " : cout), x > 1) cout << x+1
Run Code Online (Sandbox Code Playgroud)

这是一个"标准"逗号操作员技巧,允许在if条件内评估其他表达式,而不会影响最终采用的分支.

在这种情况下,添加了一个表达式:一个评估原始条件的三元运算符x > 0.产生所需副作用的表达式(不是声明,但此限制无关紧要)放在三元的"真"分支中.完全没有关系"假"分支评估的内容,只要它与"真实"分支的结果相同(或可以隐式转换为).

这里"true"分支返回一个ostream&,所以最简单的方法是cout从"false"分支返回并将其称为一天.

回答原始问题

在最初发布的情况下(用xy)宏将是

#define OUT(x) if((x > 0 ? y = x : 0), x > 1) cout << x+1
Run Code Online (Sandbox Code Playgroud)

对于这个具体案例,也可以写成

#define OUT(x) if((y = x > 0 ? x : y), x > 1) cout << x+1
Run Code Online (Sandbox Code Playgroud)

看到它在行动.