带有2个参数的C ++预处理器宏

时间:2013-08-29 12:04:19

标签: c++ c-preprocessor

我有以下宏:

 #define LOG(level,text)

我想定义包含级别和文本的宏:

#define MY_LOG_MESSAGE LEVEL1,"This is my log"

所以后者我可以跑:

  LOG(MY_LOG_MESSAGE);

gcc发出预处理错误:

  

错误:宏“LOG”需要2个参数,但只有1个

有什么想法吗?

8 个答案:

答案 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. 在识别出类似函数宏的调用参数之后,将发生参数替换。替换列表中的参数,除非前面有#或{{ 1}}预处理令牌或后跟##预处理令牌(见下文),在其中包含的所有宏都已扩展后被相应的参数替换。在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分;没有其他预处理令牌可供使用。
  2.   

这里说,作为另一个宏的参数传递的宏在后扩展,以便识别调用类函数宏的参数。

然后你也可以强制预处理器扩展宏:

##

答案 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)

即可