重载C宏

mul*_*lle 13 c c++ overloading c-preprocessor

有没有更好的方法来"重载"像这样的宏?我需要一个接受各种参数的宏.

#define DEBUG_TRACE_1(p1) std::string p[] = {p1}; log _log(__FUNCTION__, p, 1)
#define DEBUG_TRACE_2(p1, p2) std::string p[] = {p1, p2}; log _log(__FUNCTION__, p, 2)
#define DEBUG_TRACE_3(p1, p2, p3) std::string p[] = {p1, p2, p3}; log _log(__FUNCTION__, p, 3)
#define DEBUG_TRACE_4(p1, p2, p3, p4) std::string p[] = {p1, p2, p3, p4}; log _log(__FUNCTION__, p, 4)
#define DEBUG_TRACE_5(p1, p2, p3, p4, p5) std::string p[] = {p1, p2, p3, p4, p5}; log _log(__FUNCTION__, p, 5)
Run Code Online (Sandbox Code Playgroud)

这样称呼

DEBUG_TRACE_2("more", "params");
Run Code Online (Sandbox Code Playgroud)

小智 21

执行特定示例的最简单方法是使用可变参数宏:

#define DEBUG_TRACE(...)                                        \
    do {                                                        \
        std::string p[] = { __VA_ARGS__ };                      \
        log _log(__FUNCTION__, p, (sizeof p) / (sizeof p[0]));  \
    } while (0)
Run Code Online (Sandbox Code Playgroud)

几个笔记:

  1. __VA_ARGS__ 是提供给宏的逗号分隔参数列表的名称
  2. sizeof由于p是静态数组,因此您可以查看在您的情况下使用的数量
  3. 在do..while中包含宏代码通常被认为是一种很好的做法,因为它为变量(p)提供了一个块作用域,因此用户仍然可以在宏之外有一个同名的变量,而while(0)部分很好地接受一个分号如果声明,之后不会破坏一行

如果你需要比这更多的灵活性,你可以使用一个非常巧妙的技巧,允许你明确地"重载"宏,使用不同数量的参数完全不同的行为.但是,这使得代码更加复杂,只有在绝对必要的情况下才能使用.由于似乎变量参数对你的用例没问题,我只提供一个链接:http: //efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/


a_m*_*m0d 14

可以在宏中使用标准的C/C++可变参数args,至少在gcc中使用(编辑:显然它们是标准化的,MS c编译器也有它们).

有关其工作原理的一些信息,请参阅此页面.

此网站还有另一个问题,可能对您有所帮助.

  • Variadic宏在C99和C++ 11中标准化:http://en.wikipedia.org/wiki/Variadic_macro (5认同)
  • 在C++ 11中也支持它:"如果宏定义中的标识符列表中有一个`...`,那么尾随参数(包括任何分隔逗号预处理标记)将合并为一个项目:变量参数.如此组合的参数的数量是这样的,在合并之后,参数的数量比宏定义"..."中的参数数量多一个.替换列表中出现的标识符`__VA_ARGS__`应该被处理好像它是一个参数,变量参数应该形成用于替换它的预处理标记." (2认同)