高功率C ++宏 - 用于生成过载的循环扩展

时间:2014-09-27 23:13:51

标签: c++ c-preprocessor

要点:

简而言之,可以使用几个宏来复制函数定义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 ) ) \
    { \
    } \
)

有没有人知道如何单独使用宏来实现这一目标?

1 个答案:

答案 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 )

以下是LOOPPRINTITERATE的定义。请注意,LOOPPRINT仅对,运营商的使用有所不同。

#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_NPRINT_NITERATE_N形式的更多递归宏,即可扩展上限。