C++如何让预处理器优先展开宏参数实现循环展开宏动态传值
问题根因
C/C++预处理器有明确的展开规则:如果宏参数会被用于#(字符串化)或者##(令牌拼接)操作,那么参数不会被预先展开,会直接参与拼接运算。所以你传入的MAX没有被替换为5,直接和unroll拼接成了不存在的unrollMAX,导致编译报错。
解决方法
增加一层中间宏,把令牌拼接操作移到内层宏中,外层宏的参数会先完成展开再传入内层参与拼接,调整后的完整代码如下:
#include <iostream> using namespace std; #define MAX 5 #define unroll1(expr) expr(); #define unroll2(expr) expr(); unroll1(expr); #define unroll3(expr) expr(); unroll2(expr); #define unroll4(expr) expr(); unroll3(expr); #define unroll5(expr) expr(); unroll4(expr); #define unroll6(expr) expr(); unroll5(expr); #define unroll7(expr) expr(); unroll6(expr); #define unroll8(expr) expr(); unroll7(expr); // 内层宏负责实际的令牌拼接 #define UNROLL_INNER(num, expr) unroll##num(expr); // 外层宏负责触发参数预先展开 #define unroll(num, expr) UNROLL_INNER(num, expr) void print() {cout << "Hello World!" << endl;} int main() { unroll(MAX, print); unroll(MAX, print); unroll(MAX, print); return 0; }
展开流程说明
- 调用
unroll(MAX, print)时,外层unroll宏的参数MAX先被展开为5 - 展开后的参数传入
UNROLL_INNER,执行拼接得到unroll5(print) - 最终正常展开为对应次数的调用代码
这种方案下只需要修改MAX的宏定义即可全局调整循环展开次数,不需要改动任何调用位置,完全满足可维护性要求。
内容的提问来源于stack exchange,提问作者Lauren S
相关产品推荐
相关产品推荐

