2

以下は#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))。
それを機能させる方法が見つかりません。定義に中括弧を入れることができないことを考慮してください。そうしないと、挿入演算子を使用できなくなります。

4

2 に答える 2

5

「こんにちは」を印刷するように更新

それはこのように行うことができます(ああ醜いです!):

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

ifこれは「標準」のコンマ演算子のトリックであり、最終的に取得される分岐に影響を与えることなく、条件内で追加の式を評価できるようにします。

この場合、1つの式が追加されます。元の条件を評価する3項演算子ですx > 0。目的の副作用を生成する式(ステートメントではありませんが、この制限はここでは重要ではありません)は、3項の「真の」ブランチに配置されます。「true」ブランチの結果と同じタイプである(または暗黙的に変換できる)限り、「false」ブランチが何に評価されるかはまったく問題ではありません。

ここで、「true」ブランチはostream&を返すので、最も簡単な方法はcout、「false」ブランチからも戻って、それを1日と呼ぶことです。

元の質問への回答

最初に投稿されたケース(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

実際の動作をご覧ください

于 2012-05-16T10:34:48.013 に答える
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;
}
于 2012-05-16T10:27:11.387 に答える