C/C++ 预处理器:每隔一个可变参数提取一次
C/C++ preprocessor: extract every second variadic parameter
有没有办法从 C/C++ 预处理器中的可变参数列表中提取每隔一个参数?
我想编写一个宏来通过以下方式为接口方法生成样板代码:
#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
的派生词;
我正在寻找 EVERY_SECOND
宏。
这是您要求的工作示例
#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 个参数),但我认为您可以看到如何添加更多支持的模式。由于预处理器的限制
,如果不明确定义每个参数数量,就无法做到这一点
玩得开心!
编辑:
我还想指出,这可以改进,这样您就不必指定 _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__)); \
}
有没有办法从 C/C++ 预处理器中的可变参数列表中提取每隔一个参数?
我想编写一个宏来通过以下方式为接口方法生成样板代码:
#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
的派生词;
我正在寻找 EVERY_SECOND
宏。
这是您要求的工作示例
#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 个参数),但我认为您可以看到如何添加更多支持的模式。由于预处理器的限制
,如果不明确定义每个参数数量,就无法做到这一点玩得开心!
编辑:
我还想指出,这可以改进,这样您就不必指定 _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__)); \
}