我有以下宏:
#define LOG(level,text)
我想定义包含级别和文本的宏:
#define MY_LOG_MESSAGE LEVEL1,"This is my log"
所以后者我可以跑:
LOG(MY_LOG_MESSAGE);
gcc发出预处理错误:
错误:宏“LOG”需要2个参数,但只有1个
有什么想法吗?
答案 0 :(得分:2)
您必须说服预处理程序在尝试展开MY_LOG_MESSAGE
之前展开LOG()
宏。这个can be done使用一个简单的帮助宏:
#define LOG1(x) LOG(x)
LOG1(MY_LOG_MESSAGE);
LOG1()
的参数会在其正文中展开,从而导致对LOG()
的有效调用。
答案 1 :(得分:2)
这与sth's answer非常相似,但允许使用一个或两个参数:
#define LOG_(level,text) implementation
#define LOG(...) LOG_(__VA_ARGS__)
#define MY_LOG_MESSAGE LEVEL1,"This is my log"
LOG(MY_LOG_MESSAGE);
LOG(LEVEL2, "Another log");
关键是LOG
导致参数在调用LOG_
之前被扩展,因此在两种情况下都给它两个参数。
答案 2 :(得分:1)
如果你对每条日志消息都使用了一个定义,也许可以这样做:
#define LOG_MY_MESSAGE LOG(LEVEL1, "This is my log")
在代码中简单地用作
LOG_MY_MESSAGE
答案 3 :(得分:1)
这不能以这种方式工作。对于预处理器,当需要两个参数时,你只给LOG
MACRO一个参数。
你可以通过做一些简单的事情来解决它:
#define MY_LOG_MESSAGE LOG(LEVEL1, "This is my log")
并使用它:
MY_LOG_MESSAGE
说明:
在案件中:
#define LOG(level,text)
#define MY_LOG_MESSAGE LEVEL1,"This is my log"
LOG(MY_LOG_MESSAGE);
预处理器在看到对MY_LOG_MESSAGE
的调用时不会替换宏LOG
,它会将其作为参数传递(如函数)。
只有在此之后,当预处理器将替换LOG
宏时,它将重新扫描替换列表以查看是否还有更多宏要处理。
来自标准:
16.3.1参数替换[cpp.subst]
- 在识别出类似函数宏的调用参数之后,将发生参数替换。替换列表中的参数,除非前面有
醇>#
或{{ 1}}预处理令牌或后跟##
预处理令牌(见下文),在其中包含的所有宏都已扩展后被相应的参数替换。在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分;没有其他预处理令牌可供使用。
这里说,作为另一个宏的参数传递的宏在后扩展,以便识别调用类函数宏的参数。
然后你也可以强制预处理器扩展宏:
##
答案 4 :(得分:1)
#define ELOG(message) log(LEVEL_ERR,message)
#define WLOG(message) log(LEVEL_WARN,message)
以便您可以将其用作
ELOG("This is error msg")
或WLOG("Warning msg")
假设你有一个功能
void log(int loglevel,char* msg)
答案 5 :(得分:0)
是的,像这样定义LOG:
#define LOG(text)
然后LOG只收到1个参数,您可以将它与消息一起使用
LOG(MY_LOG_MESSAGE);
答案 6 :(得分:0)
预处理器从每个文件的开头到结尾,立即用替换标记列表替换任何宏。在您的情况下,LOG
首先被替换,在MY_LOG_MESSAGE
被2个参数替换之前,因此错误。
答案 7 :(得分:0)
MY_LOG_MESSAGE
将被预处理器视为一个参数,因为它是一个预处理器指令。 LEVEL1,"This is my log"
包含在MY_LOG_MESSAGE
中,并在其他预处理程序指令中用作单个预处理程序参数。
用于调用
之类的简单函数void DoLogging(Level level, const std::string& msg)
您的宏将按照您的预期进行处理。所以DoLogging(MY_LOG_MESSAGE)
会奏效。它将在这里扩展,因为它not
用作另一个预处理器指令的参数,但在real
函数内。有什么可以帮助是这样的:
#define MY_LOG_MESSAGE LOG(LEVEL1, "My message")
此外,如果您指出了多个LOG() - 宏,只需将其用作MY_LOG_MESSAGE的参数,如下所示:
#define MY_LOG_MESSAGE(logger) logger(LEVEL1, "My message")
在您的代码中,只需将其称为MY_LOG_MESSAGE(LOG)