《产生式元编程》第一章 宏编程计数引原理
引言
自 C 以来,宏为代码生成工具。至 C++98 则有模板,泛型编程日益盛行。迄于 C++20,引编译期表达式,添 Concepts,元编程基础支持始渐完善。由此元编程之技稍简。而静态反射乃元编程系统之核心,却迟久未至,产生式元编程遂仍繁复。
所述元编程之书文,指不胜屈,其间也以编译期计算为主,奇技淫巧,小大靡遗。而于产生式元编程,言者寥寥,常见于库中直用。于是有此系列,略述浅见,供同道者读阅之。
产生式元编程,即为编译期代码生成的技术,各类系统,特性不侔,用法与能力亦有所殊。是以本系列跨度稍大,然只涉标准,不论自成之法,预计十章左右,从旧有到未来之特性,俱可囊括。
问题
代码生成以宏为先,虽是旧工具,然方今模板元编程的能力尚有不足,在产生式元编程的核心特性「源码注入」进入标准之前,它仍是一种常用的代码生成工具。
宏编程得从可变宏参数开始谈起,可变模板参数的个数可以通过 sizeof...(args) 获取,宏里面如何操作呢?便是本章的问题。
接着便逐步分析问题,实现需求,其间穿插宏编程之原理。
分析与实现
宏只有替换这一个功能,所谓的复杂代码生成功能,都是基于这一核心理念演绎出来的。故小步慢走,循序渐进,便可降低理解难度。
问题是获取宏参数包的个数,第一步应该规范过程。
过程的输入是一系列对象,对象类型和个数是变化的;过程的输出是一个值,值应该等于输入对象的个数。如果将输入替换为任何类型的其他对象,只要个数没变,结果也应保持不变。
于是通过宏函数表示出过程原型:
#define COUNT_VARARGS(...) N
根据宏的唯一功能可知,输出只能是一个值。依此便可否定遍历迭代之类的常规方式,可以考虑多加一层宏,通过由特殊到普遍的思想来不断分析,推出最终结果。
#define GET_VARARGS(a) 1
#define COUNT_VARARGS(...) GET_VARARGS(__VA_ARGS__)
目前这种实现只能支持一个参数的个数识别,可通过假设,在特殊的基础上逐次增加参数。于是得到:
#define GET_VARARGS(a, b) 2
#define GET_VARARGS(a) 1
#define… Continue Reading