C++模板的替代品?
我认为元编程非常酷。特别是,我喜欢lisp宏。但是,我认为C++模板吸引因为:
1.他们减慢编译时间(即使预编译的头文件,如果你包含任何他的STL的东西,最终是50MB大)。
2.它们给出了可怕的编译器/语法错误,这些错误是不合理的
3.它们并不是因为复杂的元编程而被设计出来的(对于素数/生成模拟器的错误,图灵完成是件大事那天)。尽管如此,C++元编程是否还有一个不错的选择?像C++模板的替代品?
* .m - >元编译器 - > * .cpp - > g ++ - >可执行文件?
编辑:
我沿着线thikning“自定义代码代脚本。” 我只是想知道是否有一套非常好的一套。
如果您使用C++,我认为您唯一可行的选择是直接preprocessor macros或自定义code-generation。
您描述的工作流程基本上等于某种形式的代码生成,您可以将.m文件预处理为可编译的C++代码。 SWIG是一个很好的例子。我个人很喜欢用Python编写代码生成器,但我认为任何脚本语言都会一样好。一个可能会使用的包是cog,来自我们自己的Ned Batchelder :)
我不确定这是应该需要的,我使用了代码生成器来生成C++代码。 尤其是python猎豹。您基本上将直接的Python代码嵌入到您的C++代码中,并通过猎豹预处理器运行。与使用模板或C++预处理器相比,它允许执行相当复杂的计算,并且您可以获得所有的Python库和扩展。另一方面,如果出现错误,它会使调试更加困难。如果您有兴趣,我可以提供一些示例和Emacs模式来编辑猎豹C++程序。
如果您需要的功能不够强大,并且只想保留在C++ C中,请参阅boost预处理器,here。这需要一点时间来适应它,但可以使生活很容易,当重复代码是参与
没关系,我粘贴猎豹例子,给我几分钟:
#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
for(int a = 0; a < $N; ++a) {
/// for functions in block
%for ii, (fi,fj) in enumerate(fb)
%set i = ii + ifb
/// can also use (ix,iy,iz)=fi[0:2], need to clean up when not lazy
%set ix = fi[0]
%set iy = fi[1]
%set iz = fi[2]
%set jx = fj[0]
%set jy = fj[1]
%set jz = fj[2]
q$(i) += Ix(a,$(ix),$(jx))*Iy(a,$(iy),$(jy))*Iz(a,$(iz),$(jz));
%end for
/// end for functions in block
}
产生(运行后cheetah ...
)
#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
for(int a = 0; a < 6; ++a) {
q0 += Ix(a,0,1)*Iy(a,0,0)*Iz(a,0,0);
q1 += Ix(a,1,1)*Iy(a,0,0)*Iz(a,0,0);
q2 += Ix(a,0,1)*Iy(a,1,0)*Iz(a,0,0);
q3 += Ix(a,0,1)*Iy(a,0,0)*Iz(a,1,0);
q4 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,0,0);
q5 += Ix(a,1,0)*Iy(a,0,1)*Iz(a,0,0);
q6 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
q7 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
q8 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
q9 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
}
这是一个常规的C++代码
线开始%是由预猎豹解释为Python语句处理器。 ///是猎豹的评论。默认使用#作为python语句,但是我改变它们以避免与C预处理器指令冲突。必须使用%end
来终止python块。以$开头的C++代码中的变量被python变量替代。
你想使用boost预处理器的例子吗?
请详细解释。 – anon 2010-01-28 01:20:37
我一直在做类似于这个使用Mako的东西;我找到了这个,同时寻找更为标准的选择。 – 2010-08-19 19:55:54
代码生成是最好的答案...
您还应该看看Linux内核如何链接列表。
Linux Kernel Linked List Explained
的基本思路是不是具有嵌入在一些结构的类型(比如用next和prev指针,一个典型的列表实现),你必须嵌入到结构中的内核列表结构.. 。心情弯曲,但看看这篇文章...我从来没有想过类型安全的泛型是可能的C,直到我看到这....
大多数人坚持试图从他们最喜欢的语言内部元程序。由于模板元编程的原因,C++被视为典型例子。虽然它的作品,它是痛苦和笨拙的。我发现它告诉人们在Stroustrop将它添加到语言之后发现它具有图灵功能;尽管我怀疑他现在会抱怨它,但我认为他甚至不认为它会像他这样做。
但是大多数编程语言没有元编程功能。 (或者它们可能具有弱或笨拙的能力:)
解决此问题的方法是使用 program transformation tools从以外的进行元编程。这些工具可以解析源代码,并对其进行任意转换(这就是元编程无论如何),然后吐出修改过的程序。
如果您有一个通用的程序转换系统,可以解析任意语言,那么您可以使用任何您喜欢的语言进行元编程。 请参阅我们的DMS Software Reengineering Toolkit,该工具对于C,C++,Java,C#,COBOL,PHP和许多其他编程语言具有健壮的前端,并且已用于所有这些元编程。
此方法非常有用,因为它提供了一种常规的方法论方法,可以为任何您想要操作的语言提供元编程方法。您不必等待语言设计人员和实施人员实施,也不必忍受他们可以想象或实际执行的限制,或者支付所需的所有反射数据的运行时间空间/时间价格以支持它。
尽管TM是图灵功能,程序转换比C++模板元编程更强大!原因是TM可以从模板生成任意代码,但不能修改非模板代码。如果你坚持,程序转换可以模拟TM,并且至少也是如此强大,但它也可以对非模板代码进行任意更改。因此,严格来说更强大。
就像TM一样,使用程序转换需要一些努力来学习和应用。但能够以任意方式操作程序似乎非常有用。 (我们已经对使用DMS的超大型C++应用程序进行了体系结构重组,但TM不能做到这一点)。
另请参阅http://*.com/a/21358087/120163 – 2014-01-26 01:01:20
如果C++ 0x是一个选项,那么可以将一些模板元编程问题简化为编译时执行的一组constexpr函数。例如,考虑compile-time regex matcher using constexpr。 constexpr函数也是C++模板元程序的faster。
如果您正在进行函数式编程,还可以使用其他几个选项。
C++ Template Metaprogramming with Embedded Haskell
Meta Towards a Functional-Style Interface for C++ Template Metaprograms
你想生成或计算出什么样的东西?结构?直线功能?意大利面代码?状态机? – Potatoswatter 2010-01-28 03:15:38