c++ - 具有零个或多个附加参数的可变参数宏

标签 c++ c macros c-preprocessor

我有一个宏用于检查某些测试方法的结果:

#define Eval(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }

我想得到这个功能:

Eval(Check_1(),"Check1 failed."); // case 1
Eval(Check_2()); // case 2
Eval(Check_3(), "some variable=%i", variableValue); // case 3

在情况 1 中,我想向用户写评论(“Check1 失败”),然后返回 -1(这是工作)。 在情况 2 中,我只想从方法返回,而不是为用户打印任何信息。所以我必须检测空注释的情况而不是调用 printf() - 这是行不通的。

如果任何“Check_x”方法失败,我需要通过返回代码-1退出当前方法;

有什么办法可以用宏来做到这一点吗?

这里有非常相似的问题:Standard alternative to GCC's ##VA_ARGS trick? ,但我无法根据我的情况修改此代码。

编辑: 我使用C99标准。 在我的代码案例 2 的当前版本中,编译时出现错误“预期表达式”(我认为这是因为逗号和空参数)。 我还需要使用案例 3 来打印附加信息(变量值)。 所以,第二个参数实际上不是简单的字符串。

编辑2: 我得到了我的任务的解决方案。 Here I find it

// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N

// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs

#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)

#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }

#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)

我这样使用它:

EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);

非常感谢 Jens Gustedt 和 rmn ( http://efesx.com/ )

最佳答案

// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N

// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs

#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)

#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }

#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)

我这样使用它:

EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);

关于c++ - 具有零个或多个附加参数的可变参数宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35457496/

相关文章:

c++ - 创建任意大小的多维 vector

c++ - 在没有 move 构造函数的情况下返回不可复制对象的解决方法

c - C 编程中 hash(#) 的语法复杂化

visual-studio-2012 - 我应该如何在 VS2012 中更改 QTDIR 的值

c++ - 是否有一个用于ifstream和ofstream的宏,或一种缩短ifstream/ofstream的方法?

C++ HashTable,两个相同的实现,但一个给出错误

c++ - 如何使用 msvc10 和 ICU 编译 boost 1.54?

c - 矩阵和 vector 乘法优化算法

SFMT 与 Mersenne Twister 和 Ran2 的比较

c - union 体中的 char 字节是否颠倒?