如何用Boost PP或C++11实现多类前置声明的批量宏定义?
解决方案:实现可变参数的类前置声明宏
Boost.Preprocessor 方案
你之前的问题在于BOOST_PP_REPEAT仅按固定次数重复宏调用,无法关联到可变参数的每个具体元素。Boost.Preprocessor提供了专门处理可变参数的工具,我们可以通过序列转换+遍历的方式实现需求:
#include <boost/preprocessor/variadic/to_seq.hpp> #include <boost/preprocessor/seq/for_each.hpp> #define CLASS(C) class C; // 辅助回调宏:提取序列元素并调用CLASS #define CLASS_WRAPPER(_, unused, elem) CLASS(elem) // 主宏:将可变参数转为预处理序列,再遍历展开 #define CLASSES(...) BOOST_PP_SEQ_FOR_EACH(CLASS_WRAPPER, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) // 使用示例 CLASSES(Foo, Bar, Golf) // 展开结果:class Foo; class Bar; class Golf;
原理说明
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__):把Foo, Bar, Golf这类可变参数转换为预处理序列(Foo)(Bar)(Golf)BOOST_PP_SEQ_FOR_EACH:遍历序列中的每个元素,对每个元素调用CLASS_WRAPPER,最终触发每个元素的CLASS(elem)展开
纯C++11 非Boost方案
如果无法使用Boost,C++11可以通过递归宏+参数计数的方式实现(注:此方案需预先设定支持的最大参数个数,以下示例支持最多10个参数):
#define CLASS(C) class C; // 辅助宏:计算可变参数的个数 #define COUNT_ARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N #define GET_ARG_COUNT(...) COUNT_ARGS(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1) // 分层递归展开宏 #define CLASSES_1(C) CLASS(C) #define CLASSES_2(C1, C2) CLASS(C1) CLASSES_1(C2) #define CLASSES_3(C1, C2, C3) CLASS(C1) CLASSES_2(C2, C3) #define CLASSES_4(C1, C2, C3, C4) CLASS(C1) CLASSES_3(C2, C3, C4) // 可按需扩展到CLASSES_5至CLASSES_10 // 主宏:根据参数个数匹配对应展开宏 #define CLASSES(...) CLASSES_##GET_ARG_COUNT(__VA_ARGS__)(__VA_ARGS__) // 使用示例 CLASSES(Foo, Bar, Golf) // 展开结果:class Foo; class Bar; class Golf;
原理说明
GET_ARG_COUNT:通过占位符与参数列表的匹配,返回可变参数的总个数CLASSES_##GET_ARG_COUNT(...):通过宏拼接语法,根据参数个数调用对应的CLASSES_N宏,逐层递归展开每个参数的CLASS声明
内容的提问来源于stack exchange,提问作者Constantinos Glynos
相关产品推荐
相关产品推荐

