8

トレース、デバッグ、情報、エラーなど、いくつかのレベルのログがあると仮定しましょう。次のコードを書く方法があるかどうか疑問に思いました。

enum log_level = {trace, debug, info, error};

log_level global_log_level = info;

void log(log_level level, string& message){
    if (level >= global_log_level){
        std::cout << message << std::endl;
    }
}

string create_message(){
    ...
}

log_level level = debug;
log (level, create_message());

レベルがglobal_severity_levelよりも小さい場合、create_messageは呼び出されません。実際、create_messageは非常に長くなる可能性があり、文字列を作成する対象が何であってもです。「デバッグ」ログが多数ある場合、非デバッグモードで実行すると、それらのログがかなりのオーバーヘッドになる可能性があります。

関数「log」がマクロであり、severity> minimum_severityの場合にのみcreate_message()を呼び出す場合、これを行うことが可能であることを私は知っています。しかし、マクロなしでこれを行う別の方法はありませんか?

編集

上記では、create_messageを指定しませんでした。これは、特に次のようなものである可能性があるためです。

log(level, "Created object " + my_object.getName());

この場合、プログラマーがログを呼び出すための比較的透過的な方法で、完全な文字列が作成されないようにログを書き込む方法はありますか?

どうもありがとう

4

4 に答える 4

6

いくつかの選択肢があります。興味深いのは、create_messageとして渡しstd::function<std::string()>、 内から呼び出すことですlog:

void log(log_level level, std::function<std::string()> message_creator){
    if (level >= global_log_level){
        std::cout << message_creator() << std::endl;
    }
}

次に、次のように呼び出します。

log(level, create_message);

ラムダでラップすると、任意の式を引数として使用できます。

log(level, [&](){ return "Created object " + my_object.getName(); });

(コメントで説明したように)引数をまったく評価したくない場合は、呼び出しの外でレベルを確認する必要があります。

if (level >= global_log_level) {
  log(level, create_message());
}
于 2013-02-02T18:50:44.033 に答える
6

@sftrabbit に似ていますが、@ipc によって提案されています。

テンプレートを使用して std::function 機構を回避すると、コンパイラはこれをインライン化できる可能性があるため、結果的に高速になることが期待されます。

template< typename F >
void log(log_level level, F message_creator){
    if (level >= global_log_level){
        std::cout << message_creator() << std::endl;
    }
}
于 2013-02-02T19:31:55.820 に答える
1

@sftrabbit の回答が優先されます。ただし、log() を変更したくない場合は、次のように呼び出すことができます。

log (level, (level >= global_log_level)? create_message() : "");
于 2013-02-02T18:58:09.767 に答える
1

マクロを作成できます



    #define log(level, message) { \
    if(level >= global_log_level) {\
    cout << message; }}

今電話したら

log(debug, create_message());
create_message は、デバッグ レベルが目的のレベルである場合にのみ呼び出されます。

于 2013-02-02T19:25:54.040 に答える