首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++延迟日志记录(不带C++11)

C++延迟日志记录(不带C++11)
EN

Stack Overflow用户
提问于 2016-08-25 05:26:46
回答 2查看 183关注 0票数 2

目前,我们的代码库有很多代码,如下所示:

代码语言:javascript
复制
void log(int level, const char *msg) {
    // logLevel is some global int defining which messages to log
    if (level <= logLevel) {
        cout << msg << endl;
    }
}

...

int someNum = 3;
if (1 <= logLevel) {
    char msg[200];
    sprintf(msg, "Some format %d", someNum);
    log(1, msg);
}

我们使用的是Visual Studio2008,因此不能使用C++11的任何功能。有没有一种干净的方法可以将闭包传递给日志方法,这样我就可以删除重复的"if“条件?例如,我正在寻找与pre C++11语法中的以下代码等效的代码:

代码语言:javascript
复制
void log(int level, std::function<std::string ()> getMessage) {
    if (level <= logLevel) {
        cout << getMessage() << endl;
    }
}

...

int someNum = 3;
log(1, [someNum]() -> std::string {
    std::ostringstream sstream;
    sstream << "Some format " << someNum;
    return sstream.str();
});

我能想到的最好的结果是:

代码语言:javascript
复制
struct LogMessage {
    virtual std::string operator()() const = 0;
};

void log(int level, const LogMessage &getMessage) {
    if (level <= logLevel) {
        cout << getMessage() << endl;
    }
}

...

struct X : public LogMessage {
    X(int num) : myNum(num) { }
    std::string operator()() const {
        std::ostringstream out;
        out << "Some format " << myNum;
        return out.str();
    }
    private: const int myNum;
} a(someNum);
log(1, a);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-25 05:35:38

即使通常不推荐使用宏,但在这种特定情况下,它们可能会有所帮助,特别是如果所有文本都可以由streams处理的话。

让你的log函数成为一个宏:

代码语言:javascript
复制
#define LOG(level, msg) { if (level <= logLevel) { cout << msg << endl; } }

然后,如果你这样做了:

代码语言:javascript
复制
LOG( 1, "Some format " << someNum )

仅当日志级别条件为true时,才会执行if测试,并且仅执行宏的第二个参数中的一个和任何复杂格式设置。

注意:对于使用sprintf的现有行,您仍然需要声明一个函数...:

代码语言:javascript
复制
inline std::string printNum( int someNum )
{
    char msg[200];
    sprintf(msg, "Some format %d", someNum);
    return msg;
}

LOG( 1, printNum(3) )
票数 2
EN

Stack Overflow用户

发布于 2020-02-01 02:46:34

要补充@jpo38提供的答案,只需添加另一个宏来接受可变参数,以支持printf-style函数:

代码语言:javascript
复制
#define LOGF(LEVEL, ...)\
    if ((LEVEL) <= logLevel) {\
        char msg[200];\
        sprintf(msg, __VA_ARGS__);\
        log((LEVEL), msg);\
    }

然后,下面的任一调用都将产生相同的输出:

代码语言:javascript
复制
LOG(1, "Some format " << someNum);
LOGF(1, "Some format %d", someNum);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39133286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档