【问题标题】:Overload C macros重载 C 宏
【发布时间】:2012-02-11 19:05:49
【问题描述】:

有没有更好的方法来“重载”这样的宏?我需要一个可以接受不同数量参数的宏。

#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)

这样称呼

DEBUG_TRACE_2("more", "params");

【问题讨论】:

  • 在 C++(不了解 ANSI C)宏处理器中有一些可变参数支持,但每次我尝试使用它时,我似乎都冒着导致已知宇宙内爆的风险。跨度>
  • #define DEBUG_TRACE(ar,n) std::string p[] = ar; log _log(__FUNCTION__,p,n),用DEBUG_TRACE({"more","params"},2);打电话太简单了?

标签: c++ c overloading c-preprocessor


【解决方案1】:

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

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

几个注意事项:

  1. __VA_ARGS__ 是提供给宏的逗号分隔参数列表的名称
  2. 您可以使用 sizeof 找出您的情况有多少,因为 p 是一个静态数组
  3. 在 do..while 中围绕宏代码通常被认为是一种好的做法,因为它为变量 (p) 提供了块作用域,因此用户仍然可以在宏之外拥有同名的变量,而 while (0) 部分很好if 语句之后接受分号而不换行

如果您需要比这更大的灵活性,您可以使用一个非常巧妙的技巧,让您显式地“重载”宏,使其在不同数量的参数下表现完全不同。但是,这会使代码更加复杂,只有在绝对必要时才应该使用。由于看起来可变参数对您的用例来说很好,我将只提供一个链接: http://efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/

【讨论】:

【解决方案2】:

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

请参阅 this page 了解有关其工作原理的一些信息。

本站还有another question,可能对你有帮助。

【讨论】:

  • 可变参数宏已在 C99 和 C++11 中标准化:en.wikipedia.org/wiki/Variadic_macro
  • C++11 也支持:“如果在宏定义的标识符列表中有...,那么后面的参数,包括任何分隔的逗号预处理标记,都会合并到形成一个单一的项目:可变参数。如此组合的参数数量使得在合并后,参数的数量比宏定义中的参数数量多一个“..”标识符__VA_ARGS__出现在替换列表应被视为参数,可变参数应形成用于替换它的预处理标记。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多