本格的なログ ライブラリ (または IF ステートメント) を使用せずに、C++ でメッセージをコンソールに出力する方法と出力しない方法はありますか?
を使用してstd::cerr
いますが、これがいつ出力されるかを制御する方法はありますか?
理想的には、次のことができます。
std::cerr << "Constructor called" << endl;
このコード行を有効/無効にする方法はありますか?
本格的なログ ライブラリ (または IF ステートメント) を使用せずに、C++ でメッセージをコンソールに出力する方法と出力しない方法はありますか?
を使用してstd::cerr
いますが、これがいつ出力されるかを制御する方法はありますか?
理想的には、次のことができます。
std::cerr << "Constructor called" << endl;
このコード行を有効/無効にする方法はありますか?
「なし」とはどういう意味かわかりませんif
が、自分自身を使用せずにコードを書くことができif
ます。マクロはフラグをチェックできます。
#define CERR if (cerr_disabled) {} else std::cerr
bool cerr_disabled = false;
次に、コードで:
CERR << "error message" << std::endl;
cerr_disabled
が true の場合、何も出力されません。
このマクロ アプローチの利点は、エラー ロギングが無効になっている場合、印刷引数が評価されないことです。たとえば、関数を呼び出してより複雑なログ文字列を作成する必要がある場合:
std::string fancy_log_message () {
//...
}
CERR << fancy_log_message();
cerr_disabled
true の場合、呼び出さfancy_log_message()
れません。これは、ストリーム オブジェクト自体を抑制するだけでは達成できないことです。
簡単なアプローチはstd::ios_base::failbit
、ストリームを設定/クリアすることです:std::ios_base::failbit
が設定されている間、ストリームは動作しません [出力演算子が正しく書かれていない限り]:
std::cerr.setstate(std::ios_base::failbit);
std::cerr << "this won't show\n";
std::cerr.clear();
std::cerr << "this will show!\n";
これらの操作を使いやすくするために、マニピュレータを作成できます。次に例を示します。
std::ostream& stream_on(std::ostream& out) {
out.clear();
return out;
}
std::ostream& stream_off(std::ostream& out) {
out.setstate(std::ios_base::failbit);
return out;
}
std::cerr << stream_off << "not printed\n" << stream_on << "printed\n";
出力演算子が適切に実装されていなくても、本当にストリームを無効にしたい場合は、現在のrdbuf()
ものを (たとえば、適切な にstd::ostream::pword()
) 保存し、ストリーム バッファをnullptr
次のように設定できます。
static int stream_off_index() { static int rc = std::ios_base::xalloc(); return rc; }
std::ostream& stream_on(std::ostream& out) {
out.pword(stream_off_index) = out.rdbuf(nullptr);
return out;
}
std::ostream& stream_off(std::ostream& out) {
if (!out.rdbuf()) {
out.rdbuf(out.pword(stream_off_index);
}
return out;
}
マクロなしのソリューションは次のとおりです。
#include <iostream>
void toggle_cerr()
{
static std::streambuf* p = std::cerr.rdbuf();
std::cerr.rdbuf(std::cerr.rdbuf() ? nullptr : p);
}
int main()
{
toggle_cerr();
std::cerr << "str";
}