Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;重载宏_C++_Macros - Fatal编程技术网

C++ C++;重载宏

C++ C++;重载宏,c++,macros,C++,Macros,我看到了重载宏的不同解决方案和变通方法。但在这一点上我似乎有困难。 我有一个PRINT\u DEBUG宏,可以打印到visual studio调试器: #define DEBUG_PRINT(message, ...) _RPTN(0, message "\n", __VA_ARGS__) 现在,我想让它过载,就像这样: #define DEBUG_PRINT(message) _RPT0(0, message "\n") #define DEBUG_PRINT(messag

我看到了重载宏的不同解决方案和变通方法。但在这一点上我似乎有困难。
我有一个
PRINT\u 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__)
PRINT_DEBUG("My message");
PRINT_DEBUG("My message %s", someString);
PRINT_DEBUG("My message %s %d", someString, someValue);
这当然行不通,因为它会拾取第一个宏。
所以我检查了其他主题,发现了这个,下面是我想到的:

#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__)
我试着这样使用它:

#define DEBUG_PRINT(message)        _RPT0(0, message "\n")
#define DEBUG_PRINT(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__)
:

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

debug ("A message")
GNUCPP允许您以这种方式完全省略变量参数。在上面的示例中,编译器可能会抱怨,但因为宏的扩展在格式字符串之后仍然有额外的逗号

为了帮助解决此问题,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函数,只在调试版本中生成。

这看起来很有希望!但是我只是测试了它,MSVC编译器不喜欢这样(谢谢你的信息),你应该用C++来避免这种代码。不像C,大部分的事情都是用正确的代码实现的,而不是宏。