Macros C\C++;预处理器重载宏的不同参数

Macros C\C++;预处理器重载宏的不同参数,macros,c-preprocessor,Macros,C Preprocessor,我想在我的项目中实现登录。 我有宏,smth喜欢 __LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr; 我有一些全局记录器,第一个宏将使用全局记录器写入msg。 第二个宏将使用my_logger并写入msg 我可以用LOG\u TRACE(msg,my\u logger)实现它-但这并不好,代码更难阅读。\uuu LOG\u TRACE中的参数顺序不是必需的 Upd: 我不是说重载宏。 例如,我可以这样做 #define L

我想在我的项目中实现登录。 我有宏,smth喜欢

__LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr;
我有一些全局记录器,第一个宏将使用全局记录器写入
msg
。 第二个宏将使用
my_logger
并写入
msg

我可以用
LOG\u TRACE(msg,my\u logger)实现它-但这并不好,代码更难阅读。
\uuu LOG\u TRACE
中的参数顺序不是必需的

Upd: 我不是说重载宏。 例如,我可以这样做

#define LOG_TRACE(...) __LOG_TRACE(__VA_ARGS__, current_active)
现在我可以写作了

LOG_TRACE(msg);
LOG_TRACE(msg, logger);

但是我不想要
msg,logger
logger,msg
如果您没有可变数量的记录器,我建议您为每个记录器创建一个宏。例如(LOG_TRACE_XML、LOG_TRACE_OUT、LOG_TRACE_TXT)。因为越简单越好


<>但是更好的方法是使用LogyTraceEngult/LogyTraceEngultReals/LogyTraceEngIn,并管理这些宏使用IPC或另一宏(StIsMyMead(XML/TXT/OUT))

< P>宏重载是不允许在C或C++中进行的。但也有解决办法。这里有一篇文章将帮助你“超载”你的宏:

你不能超载预处理器宏,你的编译器会认为这是一个重新声明,而不是一个过载,因此只有第二个是有效的。
您应该尝试以不同的方式命名宏,既为了可读性,也因为这是获得所需功能的唯一途径

为什么不把它变成一个函数+do和stringify expression宏呢

#define DO_AND_RETURN_STRING_EXPR(x) (x,#x)

ov(DO_AND_RETURN_STRING_EXPR(y))
ov(my_logger, DO_AND_RETURN_STRING_EXPR(y))

(注意我还没有测试过这个代码)。<> >代码> { VAGARSXY<是对当前C++标准的扩展,但是如果你愿意玩这个,有很多实用宏来实现你想要的。特别是根据调用的参数数量实现条件的宏

#define LOG_TRACE(...)                    \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__))        \
(LOG_TRACE_(my_logger, __VA_ARGS__))      \
(LOG_TRACE_(__VA_ARGS__))
p99并不是真正的C++兼容,所以你必须适应一些事情。
代码>开始的标识符和一个大写字母或另一个下划线由C和C++保留。通常不允许双下划线用于C++,因为它们可能会干扰名称的修改。因此,最好为基本宏选择一个不同的名称

确切的要求是什么?我只有7个记录器-但问题是旧代码-我有很多旧代码,其中使用了LOG_TRACE(msg);-我不能失去兼容性。也许解决方案是一个将一切统一起来的层。或代码重构,只保留一个记录器。不管怎样,这很大程度上取决于实现。我不是说宏过载——我想要一些使用vau参数的“游戏”
#define LOG_TRACE(...)                    \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__))        \
(LOG_TRACE_(my_logger, __VA_ARGS__))      \
(LOG_TRACE_(__VA_ARGS__))