通过定义创建和调整变量名和值 我试图为C++中的日志记录类创建友好的接口。本练习的最终目标是能够创建单个定义,该定义可以根据使用的级别进行更改: MODULE_LOG(name, LOG_ALARM);

通过定义创建和调整变量名和值 我试图为C++中的日志记录类创建友好的接口。本练习的最终目标是能够创建单个定义,该定义可以根据使用的级别进行更改: MODULE_LOG(name, LOG_ALARM);,c++,variables,macros,C++,Variables,Macros,有几个级别,但我只想更改上面的定义。e、 g.要同时记录消息,它将更改为: MODULE_LOG(name, LOG_MESSAGE, LOG_ALARM); 其思想是,代码将有一个打印定义,该定义将根据模块日志定义中的请求进行定义/取消定义。因此,如果未定义LOG_消息,则消息打印宏将被定义为空,否则,如果它在将打印的列表中,则该宏将被定义为空 看到define/undefroute还没有实现,我想到了使用变量。我的想法是根据传入的级别创建一组变量。e、 g #define LOG_LEVE

有几个级别,但我只想更改上面的定义。e、 g.要同时记录消息,它将更改为:

MODULE_LOG(name, LOG_MESSAGE, LOG_ALARM);
其思想是,代码将有一个打印定义,该定义将根据模块日志定义中的请求进行定义/取消定义。因此,如果未定义LOG_消息,则消息打印宏将被定义为空,否则,如果它在将打印的列表中,则该宏将被定义为空

看到define/undefroute还没有实现,我想到了使用变量。我的想法是根据传入的级别创建一组变量。e、 g

#define LOG_LEVEL(lvl,val) \
static int LOG_LEVEL_##lvl = val

但是,我在C++中使用了变量宏,又碰到了一个问题。我似乎无法让宏创建多个名称(即,用户传入LOG_消息和LOG_报警,只创建其中一个)。此外,我还无法动态设置单个值

因此,我的问题是:

  • 是否有方法使用定义定义/取消定义打印宏的

  • 可以使用variadic宏遍历传递给它的列表并根据需要创建变量吗

  • 谢谢

    编辑-无法使用boost

  • 不可以。您不能在宏中定义
  • 不直接。通过一些努力,你可以得到丑陋的和勉强工作的宏。我并不真的建议走这条路,但这里有:
  • 您需要做的第一件事是知道一个宏得到多少个参数。没有直接的方法,但看看这个(摘自):

    现在,您可以执行以下操作:

    #define CONCAT(a,b) a##b 
    #define A(...) CONCAT(A,A_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
    #define A_1(x) something(x)
    #define A_2(x, y) something_else(x, y)
    ...
    

    您必须根据要支持的最大参数数重新重复上述定义。

    使用数组捕获varargs怎么样

    enum LogLevel { LOG_ALARM, LOG_MESSAGE /*, ...*/, LOG_UNDEFINED};
    
    #ifdef LOGGING_ENABLED
    #define MODULE_LOG(name, ...) \
    LogLevel levels[] = { __VA_ARGS__ , LOG_UNDEFINED } \
    for(int i = 0; levels[i] != LOG_UNDEFINED; i++) \
        printLog(levels[i], name) // or something
    #else
    #define MODULE_LOG(name, ...)
    #endif
    

    日志级别与模块日志有关系吗?这可以做得更优雅。@KennyTM-没有,只是一个id,用于指示可以启用/禁用的不同日志级别。这只能在函数内部工作。或者你可以在宏中定义一个函数,然后以某种方式看到它被调用了。当然,这只能在代码块中工作。它可以通过函数转换为表达式。但是人们通常想在函数(或方法)中记录一些东西,对吗?嗨,谢谢。有类似的想法,但在启动时使用类参数和函数设置静态变量,。这只涉及打印时的比较。嗨,不。我尝试了一个测试
    a(“domain-x”)
    ,但编译成
    a_VA_NUM_ARGS(“domain-x”)而不是
    A_1(“域-x”)你是对的。我编辑它试图修复它,但没有测试它。这些事情很棘手,可能需要更多的处理,但我认为这个想法可以奏效。
    
    enum LogLevel { LOG_ALARM, LOG_MESSAGE /*, ...*/, LOG_UNDEFINED};
    
    #ifdef LOGGING_ENABLED
    #define MODULE_LOG(name, ...) \
    LogLevel levels[] = { __VA_ARGS__ , LOG_UNDEFINED } \
    for(int i = 0; levels[i] != LOG_UNDEFINED; i++) \
        printLog(levels[i], name) // or something
    #else
    #define MODULE_LOG(name, ...)
    #endif