高功率C++宏-用于生成过载的循环扩展
High Powered C++ Macros - Loop Expansion for Generating Overloads
摘要:
简而言之,一对宏可以用来将一个函数定义复制N次。在第N个定义期间,指定的变量或自变量可以扩展N次。
具体地说,这个文件可以通过一些巧妙的宏以某种方式大大缩短。
我已经看到了使用#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 ) )
{
}
)
有人知道如何单独使用宏来实现这一点吗?
经过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
的递归宏,可以简单地扩展上限。
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 为什么我的for循环不能正确获取argv
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 在C++中扩展了 for 循环
- 循环浏览所有项目,其中QTREEVIEW QFILESYSTEMMODEL上具有所需的文件扩展名
- 如何将编译的扩展为函数或循环
- 扩展类c++的循环包含问题
- 高功率C++宏-用于生成过载的循环扩展
- 如何在c++中使用Detours扩展程序内函数而不进入无限循环