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

时间:2012-05-16 10:20:23

标签: c++ c-preprocessor operator-keyword insertion

以下#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)) 我找不到让它发挥作用的方法。考虑到我不能在定义中添加大括号,否则我将不允许使用插入操作符。

2 个答案:

答案 0 :(得分:5)

更新以打印“Hello”

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

#define OUT(x) if((x > 0 ? cout << "Hello " : cout), x > 1) cout << x+1

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

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

此处“true”分支返回ostream&,因此最简单的方法是从“false”分支返回cout并将其称为一天。

回答原始问题

在最初发布的案例中(xy)宏将是

#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

<强> See it in action

答案 1 :(得分:2)

创建一个函数,该函数返回对std::cout的引用,然后在MACRO中使用此函数。

#define OUT(x) MyOut( x, y )

MyOut在哪里:

std::ostream& MyOut( int x, int& yRef )
{
    if(x > 0) yRef = x;
    if(x > 1) 
    {
        std::cout << x+1;
        return std::cout;
    }
    return SomeNoOpOstream;
}