繁体   English   中英

C ++重载宏

[英]C++ Overloading Macros

我看到了重载宏的不同解决方案和解决方法。 但是我似乎在这方面有困难。
我有一个PRINT_DEBUG宏,可打印到Visual Studio调试器:

#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", __VA_ARGS__)

现在说我想像这样重载它:

#define DEBUG_PRINT(message)        _RPT0(0, message "\n")
#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", __VA_ARGS__)

这当然是行不通的,因为它将获取第一个宏。
因此,我检查了其他主题并找到了此解决方案 ,这是我想到的:

#define PRINT_DEBUG(...) _DEBUG_PRINT_SELECT(__VA_ARGS__, _DEBUG_PRINT2, _DEBUG_PRINT1, ...) (__VA_ARGS__)

#define _DEBUG_PRINT_SELECT(_1, _2, NAME, ...) NAME

#define _DEBUG_PRINT1(message)      _RPT0(0, message "\n")
#define _DEBUG_PRINT2(message, ...) _RPTN(0, message "\n", __VA_ARGS__)

我正在尝试像这样使用它:

PRINT_DEBUG("My message");
PRINT_DEBUG("My message %s", someString);
PRINT_DEBUG("My message %s %d", someString, someValue);

我真的必须根据我拥有的参数数量对每个代码进行硬编码吗? 还是有任何创造性的方式来做到这一点?

我发现的唯一解决方法是只有一个:

#define PRINT_DEBUG(message, ...)   _RPTN(0, message "\n", __VA_ARGS__);

并说我只想打印一条消息,我必须在mvsc编译器中传递第二个参数:

PRINT_DEBUG("My message", NULL);

任何帮助将非常感激! 提前致谢!

至少在GCC中,您不需要重载即可解决此问题:

#define DEBUG_PRINT(message, ...)   _RPTN(0, message "\n", ## __VA_ARGS__)

https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html

在标准C中,不允许完全省略变量参数。 但您可以传递一个空参数。 例如,此调用在ISO C中是无效的,因为字符串后没有逗号:

 debug ("A message") 

GNU CPP允许您以这种方式完全省略变量参数。 在上面的示例中,编译器会抱怨,尽管由于宏的扩展在格式字符串之后仍带有多余的逗号。

为了帮助解决此问题,CPP专门用于与令牌粘贴运算符“ ##”一起使用的变量参数。 相反,如果你写

 #define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__) 

如果变量参数被省略或为空,则'##'运算符使预处理器删除逗号之前的逗号。 如果确实在宏调用中提供了一些可变参数,则GNU CPP不会抱怨粘贴操作,而是将可变参数放在逗号之后。 就像任何其他粘贴的宏参数一样,这些参数也不是宏扩展的。

它的确取决于您使用宏的目的,但是似乎您很难做到这一点。 通常,宏的唯一目的是围绕“调试输出”,因此您可以将其关闭以用于发行版本。
在这种情况下,只需将普通函数包装在宏中即可。

#ifdef Debug
#define PRINT_DEBUG PrintDebugMessage
    enum DebugLevel {SERIOUS, MILD, IRRITATING, MISLEADING, etc};
    void PrintDebugMessage(message);
    void PrintDebugMessage(message, ...);
    void PrintDebugMessage(message, DebugLevel, ...);
    // and so on
#else
    // do nothing
    #define DebugPrint(...) 
#endif

然后在一个特殊的模块中实现您的PrintDebugMessage函数,您只能在调试版本中进行构建。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM