Generating function declaration using a macro iteration

笑着哭i 提交于 2019-11-28 11:35:18

P99 has a macro that does exactly what you want, I think, namely P99_PROTOTYPE. It has a "signature" of

P99_PROTOTYPE(RT, NAME [, AT]*)

where RT is the return type (may be void) and AT are the argument types. The list of argument types may be empty, in which case it is substituted by void.

Beware that P99 is made for C99 and not for C++. You'll encounter particular difficulties if your arguments contain commas. C++'s syntax abuse of tokens < and > as bracketing expressions for templates is particularly bad for the preprocessor. C-preprocessor and C++ are basically incompatible languages on the syntax level.

P99 gets away from the difficulties that you are facing by detecting the number of arguments that the macro receives on a call and reacts differently on the border cases.

To solve the "FOO" problem, you can select different macros depending on the arity of the variable arguments pack. Here's a first shot at that:

// These need to be updated to handle more than three arguments:
#define PP_HAS_ARGS_IMPL2(_1, _2, _3, N, ...) N
#define PP_HAS_ARGS_SOURCE() MULTI, MULTI, ONE, ERROR

#define PP_HAS_ARGS_IMPL(...) PP_HAS_ARGS_IMPL2(__VA_ARGS__)
#define PP_HAS_ARGS(...)      PP_HAS_ARGS_IMPL(__VA_ARGS__, PP_HAS_ARGS_SOURCE())

#define FOO_ONE(x)     ONE_ARG:    x
#define FOO_MULTI(...) MULTI_ARG:  __VA_ARGS__

#define FOO_DISAMBIGUATE2(has_args, ...) FOO_ ## has_args (__VA_ARGS__)
#define FOO_DISAMBIGUATE(has_args, ...) FOO_DISAMBIGUATE2(has_args, __VA_ARGS__)
#define FOO(...) FOO_DISAMBIGUATE(PP_HAS_ARGS(__VA_ARGS__), __VA_ARGS__)

Usage example:

FOO(1)     // replaced by ONE_ARG:   1
FOO(1, 2)  // replaced by MULTI_ARG: 1, 2

(I'll try to revisit this to clean it up; I think there are definitely some unneccessary macros in there. I haven't had a chance to look into the broader problem that you describe, so I'm not sure if this solves that too. There may be a simpler way to solve that problem, too... I'm not particularly familiar with variadic macros. This preprocesses cleanly on mcpp.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!