如何实现可接收代码块作为参数的C++函数
实现逻辑说明
你想要的这类语法不是原生支持的「函数接收代码块参数」,本质是通过宏封装流程结构,把用户写在后面的代码块变成宏定义结构的一部分执行,Boost.ForEach、Qt Q_FOREACH 等常用的类语法都是用这个思路实现的。
C++ 实现方案(C++11及以上版本推荐)
用临时对象+lambda的组合实现,灵活性最高,支持在代码块里直接捕获外部变量:
#include <iostream> // 前置辅助类,构造时直接执行传入的lambda struct _BlockExecutor { template<typename Callable> _BlockExecutor(Callable&& block) { std::forward<Callable>(block)(); } }; // 你的自定义宏定义 #define DO_SOMETHING_FUNC(arg1, arg2, arg3) \ /* 此处可插入任意参数前置处理逻辑 */ \ std::cout << "预处理参数:" << (arg1) << " " << (arg2) << " " << (arg3) << "\n"; \ /* 把后续代码块包装为lambda传入执行器 */ \ _BlockExecutor() = [&]()
调用效果和你给出的示例完全一致:
int main() { int a = 10, b = 20, c =30; DO_SOMETHING_FUNC(a, b, c) { // 此处为你要传入的代码块,可直接访问外部变量 std::cout << "代码块执行\n"; std::cout << "读取外部变量a: " << a << "\n"; } return 0; }
C语言实现方案
C语言无lambda特性,用多层循环结构实现单 run 逻辑即可:
#include <stdio.h> #define DO_SOMETHING_FUNC(arg1, arg2, arg3) \ /* 定义临时变量存参数,避免多次计算宏参数的副作用 */ \ int __tmp1 = (arg1), __tmp2 = (arg2), __tmp3 = (arg3); \ /* 前置处理逻辑 */ \ printf("预处理参数:%d %d %d\n", __tmp1, __tmp2, __tmp3); \ /* 单层循环保证后面的代码块只执行一次 */ \ for(int __run_flag = 0; __run_flag < 1; __run_flag++)
调用方式和C++版本完全相同。
注意事项
- 宏内定义的临时变量建议加双下划线前缀,避免和用户代码块内的变量名冲突
- 如果需要代码块可以接收宏的输出参数,直接把对应变量定义在宏的前置逻辑里即可,代码块内可直接访问
- 多语句宏建议用
do-while(0)范式包裹,避免不同上下文下的括号匹配问题
内容的提问来源于stack exchange,提问作者Vbrawl
相关产品推荐
相关产品推荐

