次の特性を持つロギング機能を設計したいと考えています。
- char* ではなく std::string に基づく
- printf のように可変数の変数をサポート
- 最初のパラメーターとして重大度レベルを受け入れます
- 重大度レベルがロギング レベルを下回る場合のフォーマット オーバーヘッドを回避
- printf と同じか、それに近い単純さ
自動型変換のため、boost::format を使用する傾向があります。しかし、ここに私が見るいくつかの問題があります:
その構文は少しぎこちなくformat("Mgr %s on pid %d is in state %s" % mgr % pid % s)
、目には少し難しいです (変数のリストの性質は、コンマなしでは明らかではありません)。ログ呼び出しは次のようになります。
mylog(INFO, format("Mgr %s on pid %d is in state %s" % mgr % pid % s));
さらに悪いことに、mylog() を実装して、フォーマット オブジェクトが構築さ れる前に INFO メッセージをログに記録しているかどうかを確認することさえ可能ですか?
私が考えたもう1つのアプローチは、printfに近いように見えますが、
mylog(INFO, "Mgr %s on pid %d is in state %s", mgr, pid, s);
あるいは
mylog_info("Mgr %s on pid %d is in state %s", mgr, pid, s);
実装は次のようになります。
mylog(int severity, string pattern, ...) {
if (severity >= LOGLEVEL) {
boost::format fmt(pattern);
for parm /* remaining parameters */ {
fmt % parm; // feed into format one at a time
}
}
}
これにより、必要になるまでフォーマットオブジェクトの構築が確実に延期されます。しかし、私が知る限り、可変引数リストをトラバースするときに、最後に到達したことを知る方法はありません!
誰かがこれを達成するための構文的に簡単なテクニックを提案できますか?
注: 私は g++ 4.4 を持っていますが、これは c++11 のすべてをサポートしているわけではありません (ただし、可変個引数テンプレートはサポートしています)。