问题
我正在寻找一个可变参数 C 预处理器宏,它将其参数和相应的格式字符串传递给函数,并根据参数的数量重复一个字符。
例如,我想要一个宏 FOO
,它扩展如下(或等效的 C 代码):
FOO(1)
→bar("d",1)
FOO(1,2)
→bar("dd",1,2)
,FOO(1,2,3)
→bar("ddd",1,2,3)
- 奖励:
FOO()
→bar("")
虽然我可以将解决方案组合到 C preprocessor macro for returning a string repeated a certain number of times和 C++ preprocessor __VA_ARGS__ number of arguments (或类似的问题)或使用 variadic macros ,这些有几个缺点,例如:
- 需要特殊的库,例如 Boost(这对我来说是一个问题),
- 依赖于编译器,
- 仅在运行时工作,
- 极其复杂。
我希望,当不单独考虑这些问题时,会出现一些更好的解决方案。
背景
我想在自动生成的代码中回调 Python C 扩展中的 Python 函数。
因此,例如,我需要 foo(1,2,3)
扩展为:
PyObject_CallObject( callback_foo, Py_Build_Value("(Oddd)",Y,1,2,3) )
我知道 foo
的所有参数都是 double ,但我不知道它们的数量。
(上面的示例有所简化。我知道它缺少一些 Py_DECREF
。)
最佳答案
使用 100% 标准 C,您可以这样做:
#define COUNT_ARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define STRTABLE (const char*[]){ "", "d", "dd", "ddd", "ddddd" } // and so on
#define FOO(...) bar(STRTABLE[COUNT_ARGS(__VA_ARGS__)], __VA_ARGS__)
在此示例中,STRTABLE
是一个复合文字查找表,其中包含一堆字符串文字作为初始值设定项列表。通过计算宏参数的数量并专门使用该数组索引,仅使用与传递给宏的参数数量相对应的初始值设定项。
完整示例:
#include <stdio.h>
#define COUNT_ARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define STRTABLE (const char*[]){ "", "d", "dd", "ddd", "ddddd" } // and so on
#define FOO(...) bar(STRTABLE[COUNT_ARGS(__VA_ARGS__)], __VA_ARGS__)
void bar(const char* fmt, ...)
{
puts(fmt);
}
int main (void)
{
FOO(1);
FOO(1,2);
FOO(1,2,3);
}
关于c - 可变参数宏包装器,可扩展为具有与参数数量对应的字符的格式字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960579/