有没有办法从C / C ++预处理器中的可变参数列表中提取每个第二个参数?
我想用以下方式编写一个宏来为接口方法生成样板代码:
sourceMat
将用作:
#define INTERFACE_FN(_NAME, _X, _Y, _N_PARAMS, ...) \
void _NAME(__VA_ARGS__) \
{ \
processing_function(_X, _Y, _N_PARAMS, EVERY_SECOND(__VA_ARGS__); \
}
void processing_function(int x, int y, int count, ...)
{
va_list params;
va_start(params, count);
while (count--) {
do_something(va_arg(params, ParentClass*));
}
va_end(params);
// do something else
}
课程INTERFACE_FN(foo, 1, 2, 0);
INTERFACE_FN(bar, 3, 4, 1, ClassX*, x);
INTERFACE_FN(jar, 5, 6, 2, ClassY*, y, ClassZ*, z);
,ClassX
,ClassY
是ClassZ
的衍生工具;
我正在寻找ParentClass
宏。
答案 0 :(得分:1)
以下是您要求的
的工作示例#define EVERY_SECOND0(...)
#define EVERY_SECOND1_(second, ...) , second
#define EVERY_SECOND1(first, ...) EVERY_SECOND1_(__VA_ARGS__)
#define EVERY_SECOND2_(second, ...) , second EVERY_SECOND1(__VA_ARGS__)
#define EVERY_SECOND2(first, ...) EVERY_SECOND2_(__VA_ARGS__)
#define EVERY_SECOND3_(second, ...) , second EVERY_SECOND2(__VA_ARGS__)
#define EVERY_SECOND3(first, ...) EVERY_SECOND3_(__VA_ARGS__)
#define EVERY_SECOND4_(second, ...) , second EVERY_SECOND3(__VA_ARGS__)
#define EVERY_SECOND4(first, ...) EVERY_SECOND4_(__VA_ARGS__)
#define EVERY_SECOND5_(second, ...) , second EVERY_SECOND4(__VA_ARGS__)
#define EVERY_SECOND5(first, ...) EVERY_SECOND5_(__VA_ARGS__)
#define COUNT_EVERY_SECOND(_1,__1,_2,__2,_3,__3,_4,__4,_5,__5,num,...) EVERY_SECOND ## num
#define EVERY_SECOND(...) COUNT_EVERY_SECOND(__VA_ARGS__,5,5,4,4,3,3,2,2,1,0)(__VA_ARGS__)
#define INTERFACE_FN(_NAME, _X, _Y, _N_PARAMS, ...) \
void _NAME(__VA_ARGS__) \
{ \
processing_function(_X, _Y, _N_PARAMS EVERY_SECOND(__VA_ARGS__)); \
}
class parentClass {};
class ClassX {};
class ClassY {};
class ClassZ {};
void processing_function(int x, int y, int count, ...)
{
va_list params;
va_start(params, count);
while (count--) {
do_something(va_arg(params, ParentClass*));
}
va_end(params);
// do something else
}
INTERFACE_FN(foo, 1, 2, 0);
INTERFACE_FN(bar, 3, 4, 1, ClassX*, x);
INTERFACE_FN(jar, 5, 6, 2, ClassY*, y, ClassZ*, z);
预处理器输出如下所示
class parentClass {};
class ClassX {};
class ClassY {};
class ClassZ {};
void processing_function(int x, int y, int count, ...)
{
va_list params;
va_start(params, count);
while (count--) {
do_something(va_arg(params, ParentClass*));
}
va_end(params);
}
void foo() { processing_function(1, 2, 0 ); };
void bar(ClassX*, x) { processing_function(3, 4, 1 , x); };
void jar(ClassY*, y, ClassZ*, z) { processing_function(5, 6, 2 , y , z); };
虽然我会给出强制性的警告,即如果没有宏,可能会有更简单的方法来做到这一点。
如果您输入奇数个参数,最后会有一个额外的逗号,但这不应该发生在您的用例中。这允许最多5对(总共10个参数),但我认为您可以看到如何添加更多支持的模式。如果没有明确定义由于预处理器限制而导致的每个args数量
,则无法执行此操作玩得开心!
我还要注意,这可以改进,以便您永远不必指定_N_PARAMS并让宏为您计算,只需添加一个宏
#define COUNT_EVERY_SECOND_(_1,__1,_2,__2,_3,__3,_4,__4,_5,__5,num,...) num
并用此
替换INTERFACE_FN
的定义
#define INTERFACE_FN(_NAME, _X, _Y, ...) \
void _NAME(__VA_ARGS__) \
{ \
processing_function(_X, _Y, COUNT_EVERY_SECOND_(__VA_ARGS__,5,ERROR,4,4,3,3,2,2,1,0) EVERY_SECOND(__VA_ARGS__)); \
}