C \ C ++预处理器用于重载宏的不同arg

时间:2011-07-27 10:49:38

标签: macros c-preprocessor

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

__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,loggerlogger,msg

5 个答案:

答案 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 ++不允许使用双下划线,因为它们可能会干扰名称修改。所以你最好为你的基本宏选择一个不同的名字。