重载C宏

问题描述 投票:13回答:2

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

#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++ c overloading c-preprocessor
2个回答
21
投票

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

#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)部分很好地接受一个分号如果声明,之后不会破坏一行

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


14
投票

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

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

这个网站上还有another question可能对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.