2012-05-02 7 views
3

今はロギングクラスを書いています。 Loggerはストリームで動作し、同時にロギングしているオブジェクトを出力します。ここではマクロは次のとおりです。ロギングのためのマクロを書く

#define OBJLOG(DL, what) DL <= this->Logger->getDebugLevel() ? *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl : this->Logger->doNothing(); 

より良い概要については、擬似コードvarientの:

#define OBJLOG(debuglevel, what) debuglevel <= logger.debuglevel ? logger.log(what) : logger.doNothing() 

全く何もしないように、doNothing関数呼び出しを回避する方法はありますか?前もって感謝します。

答えて

4
#define OBJLOG(DL, what) do { if(DL <= this->Logger->getDebugLevel()) *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl; } while(0) 

説明はWhy use apparently meaningless do-while and if-else statements in macros?を参照してください。 (do {} while(0)は、ここでは厳密には必要ではないですが、私はostreamを漏洩しないことを好むだろう。)

また、あなたは常にマクロ引数は以下のように、括弧内に使用していますラップする必要があります:あなたがすべき、

最後
#define OBJLOG(DL, what) do { if((DL) <= this->Logger->getDebugLevel()) *this->Logger << (DL) << "[" << this->Name << "]: "<< (what) << std::endl; } while(0) 

このコードを関数に移動してマクロで呼び出す(実際にマクロを使用することを望む場合)、マクロ引数を複数回評価することを避けてください。

+0

こんにちは、あなたの答えに感謝します。私はあなたが関数呼び出しにそれを移動することについて書いた最後の部分を取得しません。しかし、それは今試してみて、それを働かせる方法を見てください。 – roohan

+0

'what'パラメータの周りにカッコを置かない*かもしれません。マクロ呼び出しの考えられる構文を変更します。かっこなしでは、OBJLOG(0、 "x:" << x << "; y:" << y ")を呼び出すことができます。括弧を使用すると、(文字配列をシフトできないため)マクロ展開で構文エラーが発生します。 –

+0

マクロ引数が複数回展開された場合、式に副作用がないことを期待しています(つまり、数えないでください)。例えば。 'OBJLOG(-i?DEBUG:WARN、" foo ")'は 'i'を2回減らします。 (これは人為的な例ですが、マクロを書くときには注意してください) – Electro

1
  1. logger.log()関数はブール値を返します。トリックを行う必要がありますデバッグレベル< = logger.debuglevel & & logger.log

  • はとして、このようなあなたの述語を接続します。

  • +0

    最初のコード・バリアントを使用すると、最初のステップは必要ありません。 'Logger'オブジェクトは明白にストリームポインタであり、ストリームは暗黙的にbool式で使用できます:'(DL <= this-> Logger-> getDebugLevel()&&(* this-> Logger << ... << what << std: :endl)) '。 –

    +0

    @Robロガーにはストリーム演算子がありますが、ストリームをメンバーの1つとして含む可能性が最も高いユーザー定義クラスであると想定しました。私自身の実装はこれを行いますので、ブール変換演算子を追加する必要がありました。しかし、ただの仮定。 –

    0

    何もしない式が必要な場合は、​​を試してください。

    関連する問題