我想实现登录我的项目。 我有宏,喜欢
__LOG_TRACE(lg, expr,...) LOG_TRACE_STREAM(lg) << expr;
所以我想实现这个宏的接口 - 另一个宏,但我想支持两种类型:
LOG_TRACE(msg);
LOG_TRACE(my_logger, msg);
我有一些全局记录器,第一个宏将使用全局记录器编写msg
。
第二个宏将使用my_logger
并使用它来编写msg
。
我可以用LOG_TRACE(msg, my_logger);
制作它 - 但它不好,在代码中读取起来比较困难。 __LOG_TRACE
中的参数顺序不是必需的。
UPD: 我不是说重载宏。 看 - 例如我可以做到这一点
#define LOG_TRACE(...) __LOG_TRACE(__VA_ARGS__, current_active)
现在我可以写
了LOG_TRACE(msg);
LOG_TRACE(msg, logger);
但我不想msg,logger
和logger,msg
答案 0 :(得分:4)
C或C ++中不允许宏重载。但有一些解决方法。这是一篇有助于你超载的文章。你的宏:http://cplusplus.co.il/2010/08/31/overloading-macros/
答案 1 :(得分:2)
如果您没有可变数量的记录器,我建议您为每个记录器制作一个宏。 ex(LOG_TRACE_XML,LOG_TRACE_OUT,LOG_TRACE_TXT)。因为更简单更好。
但更好的方法是使用LOG_TRACE_ERROR / LOG_TRACE_WARNING / LOG_TRACE_INFO并使用IPC或其他宏(SET_MODE(XML / TXT / OUT))管理这些宏的行为方式
答案 2 :(得分:1)
你不能超载预处理器宏,你的编译器会认为这是重新声明,而不是重载,所以只有第二个才有效。
为了便于阅读,您应该尝试以不同的方式命名宏,因为这是您获得所需功能的唯一方法。
答案 3 :(得分:0)
为什么不把它变成函数+ do和stringify表达式宏?
#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))
(注意我还没有测试过这段代码)。
答案 4 :(得分:0)
__VA_ARGS__
是当前C ++标准的扩展,但是如果你愿意使用这个P99有很多实用程序宏来实现你想要的。特别是根据调用它们的参数数量来实现条件的宏。
#define LOG_TRACE(...) \
P99_IF_EQ_1(P99_NARG(__VA_ARGS__)) \
(LOG_TRACE_(my_logger, __VA_ARGS__)) \
(LOG_TRACE_(__VA_ARGS__))
P99与C ++不兼容,所以你必须稍微调整一下。
BTW,C和C ++保留以_
开头的标识符和大写字母或其他下划线。一般来说,C ++不允许使用双下划线,因为它们可能会干扰名称修改。所以你最好为你的基本宏选择一个不同的名字。