要点:
简而言之,可以使用几个宏来复制函数定义N次。在第N个定义期间,指定的变量或参数可以扩展N次。
非常具体this file可以通过一些聪明的宏大大缩短以某种方式。
我已经看过使用#include
指令的解决方案,我很确定不需要#include
指令。
详细信息:
我见过一个代码库,我不再有权使用某些宏来创建函数重载。我想重新创建此功能,但只能记住实现的各个部分。这个想法是一些函数重载,如下所示:
void func( int a0 )
{
}
void func( int a0, int a1 )
{
}
void func( int a0, int a1, int a2 )
{
}
可以用这样的宏创建:
void func( LOOP_ME( int a ) )
{
}
LOOP_ME是一个宏。我们的想法是将任何参数或变量包装在您希望在LOOP_ME宏中复制的函数中。
我记得代码库里面有这样的东西:
#define LOOP_ME1( x ) x##0
#define LOOP_ME2( x ) x##0, x##1
#define LOOP_ME3( x ) x##0, x##1, x##2
代码库肯定是使用宏重载技巧,如下所述:http://efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/。但是,我不记得具体在实现中使用了这个技巧。
另一个特点是函数只需要写一次。所以我的例子中func
的整个定义会被重复N次,而在我的例子中,N被硬编码为3.我不记得复制相关函数的机制,但我是猜测代码库使用了这样的东西:
INPUT_TEXT(
void func( LOOP_ME( int a ) ) \
{ \
} \
)
有没有人知道如何单独使用宏来实现这一目标?
答案 0 :(得分:1)
在评论中经过大量研究和dyp和HWalter的帮助后,我提出了一个适用于任何体面编译器的好解决方案。以下是我们想要生成的示例:
void func( int a1 )
{
int args[] = {
a1
};
args[1 - 1] = 1;
}
void func( int a1, int a2 )
{
int args[] = {
a1,
a2
};
args[1 - 1] = 1;
args[2 - 1] = 2;
}
void func( int a1, int a2, int a3 )
{
int args[] = {
a1,
a2,
a3
};
args[1 - 1] = 1;
args[2 - 1] = 2;
args[3 - 1] = 3;
}
以下是生成上述功能的代码:
#define PARAMS( N ) \
int a##N
#define COLLECT_PARAMS( N ) \
a##N
#define ACCESS_PARAMS( N ) \
args[N - 1] = N;
#define FUNC( N ) \
void func( LOOP( PARAMS, N ) ) \
{ \
int args[] = { \
LOOP( COLLECT_PARAMS, N ) \
}; \
\
PRINT( ACCESS_PARAMS, N ) \
}
ITERATE( FUNC, 3 )
以下是LOOP
,PRINT
和ITERATE
的定义。请注意,LOOP
和PRINT
仅对,
运营商的使用有所不同。
#define ITERATE_0( F )
#define ITERATE_1( F ) F( 1 )
#define ITERATE_2( F ) ITERATE_1( F ) F( 2 )
#define ITERATE_3( F ) ITERATE_2( F ) F( 3 )
#define ITERATE( F, N ) ITERATE_##N( F )
#define LOOP_0( F, N )
#define LOOP_1( F, N ) F( 1 )
#define LOOP_2( F, N ) LOOP_1( F, N ), F( 2 )
#define LOOP_3( F, N ) LOOP_2( F, N ), F( 3 )
#define LOOP( F, N ) LOOP_##N( F, N )
#define PRINT_0( F, N )
#define PRINT_1( F, N ) F( 1 )
#define PRINT_2( F, N ) PRINT_1( F, N ) F( 2 )
#define PRINT_3( F, N ) PRINT_2( F, N ) F( 3 )
#define PRINT( F, N ) PRINT_##N( F, N )
这可以通过调用宏N次来实现。称为N次的宏将生成N个函数(并且可能生成除函数之外的其他函数)。在每个调用内部循环都可以运行。内部循环递归运行N次。
将所有要生成的文本放在可调用宏内部循环中是很重要的,这样圆括号和逗号就不会搞砸宏API,因为这些宏会自行分隔宏。
N的上限为3,如果传递0则有效(不会生成任何内容)。只需通过制作LOOP_N
,PRINT_N
和ITERATE_N
形式的更多递归宏,即可扩展上限。