我正在阅读boost :: MPL作者的c ++模板元编程书。我是灵魂/凤凰图书馆的忠实粉丝。
然而我在想。使用c ++元编程模板是一件麻烦事。它不是用于那种用途。模板和宏都不支持循环。在模板中,您基本上必须通过递归。
据我了解,c ++编译过程大致如下:
模板元编程是对步骤1& 2,20年前发现有些错误。
使用实际语言不是更简单吗?我的意思是一些语言可以访问c ++语法树并操纵它,以及良好的文本处理能力。
我正在考虑像twig / django这样的模板语言,以及g ++ AST的相应钩子,以及type_traits和pod类型的原生定义。
这是否存在?我在网上找不到这样的内容。它可以实现与c ++模板元编程相同的结果(以及更多),但编译速度更快,代码更清晰,更易读。
答案 0 :(得分:10)
你想要的是program transformation system (PTS)。
这些工具通过完全超越编程语言来概括元编程(因此,与模板不同[和您的抱怨] PTS不限于您在编程语言中所说的内容。)
一般来说,PTS通过编程语言语法和漂亮的打印规则进行参数化(使其能够将感兴趣的语言P解析为AST,并从AST解析回源代码),一组转换(代表了本质)您想要进行的更改,例如“优化数组访问”)和一些“元程序”M,它将如何应用转换以实现您想要的确切目的(例如,“优化这些数组访问”但不是那些)“。
一个好的PTS允许你用嵌入在P语法中的模式语言来编写变换。因此,变换基本上表示,“如果匹配模式p,则将其替换为q”,其中p和q是表面语法版本感兴趣的代码。对于基于AST的转换规则,没有一个转换可以进行任意大量的工作(因为模式AST是固定直径的),因此需要多个转换才能实现复杂的结果。
元程序对变换进行排序;它可以以各种方式编码。 Stratego对基本变换模式语言的“策略”DSL扩展中的元节目进行编码,这是对点变换成功或失败的反应,以及树导航步骤(向上,向下,重复)。 TXL的元程序功能优于模式匹配。 DMS使用PARLANSE,一种并行编程语言,它允许在非常大的源代码集上并行地(小心地)应用变换。 Clang没有完整的源模式匹配,但有一些“AST”匹配器使语法匹配更容易一些;否则你将变换写成在树上走/走的程序代码,嵌入在用C ++本身编码的元程序中。 Rose Compiler的元程序在很大程度上就像Clang一样程序化。那里有Eclipse CDT Refactoring工具;我不太了解他们的状态,但他们没有模式定向转换,我认为元程序是用Java编写的。还有其他PTS;它们中的大多数并不像这些那样健壮或成熟。 GCC存在,但没有组织成PTS。 (把这一切都带上了一粒盐;我是DMS背后的人,所以你可能不想相信我。)
您特别想要操纵C ++。这意味着该工具必须正确地处理C ++。 Stratego和TXL目前不支持C ++,并且不太可能因为生成完整的C ++前端所付出的努力。 Clang显然有一个有用的C ++前端。因此,Rose使用EDG前端也是如此。 DMS有一个完整的C ++ 11前端,我们在大型GCC和Windows c ++代码库上构建和验证。我不确定CDT前端的成熟度;特别是,我不明白他们使用什么作为解析器。
(EDIT 2015年9月:DMS现在可以处理MS和GCC方言中的完整C ++ 14。)
你通过元编程从“内部”与“外部”交换的语言是真正的,真正神秘的“模板元编程”的可读性,通常不那么神秘的模式语法和元编程语言。恕我直言,你获得了强大的力量,因为PTS旨在操纵源代码,他们通常可以调用模板根本无法靠近的底层机器(符号表,类型信息,控制/数据流)提供的分析器。
对我而言,真正的优势在于PTS可以在任意代码边界上应用转换;大多数C ++模板只能生成代码来替换模板调用。 (特别是,在语言中实现的所有元编程/反射方案的缺陷是它们的能力总是有限的; PTS没有这样的限制)。
在我的简历中,您可以找到DMS描述的链接。更重要的是,那里有一组论文(例如,“案例研究:通过自动程序转换重新设计C ++组件模型”),描述了应用于C ++程序的大规模转换(将它们从具有复杂API的一个RTOS转变为完全不同的系统,以及从根本上重构API),可以给你一个味道,看起来像这样。 (据我所知,在各种PTS工具中,只有DMS已经应用于这个雄心勃勃的C ++转换任务。)这些论文将表明PTS操作根本不像模板元编程,不依赖于像SFINAE这样的技巧,可以做的事情没有模板元程序恕我直言可以实现。