C++模板的替代品?

问题描述:

我认为元编程非常酷。特别是,我喜欢lisp宏。但是,我认为C++模板吸引因为:
1.他们减慢编译时间(即使预编译的头文件,如果你包含任何他的STL的东西,最终是50MB大)。
2.它们给出了可怕的编译器/语法错误,这些错误是不合理的
3.它们并不是因为复杂的元编程而被设计出来的(对于素数/生成模拟器的错误,图灵完成是件大事那天)。尽管如此,C++元编程是否还有一个不错的选择?像C++模板的替代品?

* .m - >元编译器 - > * .cpp - > g ++ - >可执行文件?

编辑:

我沿着线thikning“自定义代码代脚本。” 我只是想知道是否有一套非常好的一套。

+1

你想生成或计算出什么样的东西?结构?直线功能?意大利面代码?状态机? – Potatoswatter 2010-01-28 03:15:38

如果您使用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预处理器的例子吗?

+0

请详细解释。 – anon 2010-01-28 01:20:37

+0

我一直在做类似于这个使用Mako的东西;我找到了这个,同时寻找更为标准的选择。 – 2010-08-19 19:55:54

代码生成是最好的答案...

您还应该看看Linux内核如何链接列表。

Linux Kernel Linked List Explained

的基本思路是不是具有嵌入在一些结构的类型(比如用next和prev指针,一个典型的列表实现),你必须嵌入到结构中的内核列表结构.. 。心情弯曲,但看看这篇文章...我从来没有想过类型安全的泛型是可能的C,直到我看到这....

+0

除此之外,您的示例不是类型安全的,它是无法使用的。 – rlbond 2010-01-28 01:50:53

+0

好的,好吧,不存在任何铸件...... :) – dicroce 2010-01-28 15:09:36

+0

铸件隐藏在一些宏的后面。然而对于那些以类型安全的方式做这种事情很困难或者不可能的C来说,这种技术是非常有用的。 Windows也有类似的宏('CONTAINING_RECORD()')进行链表操作。考虑到C的局限性,这是一种很好的技术。现在我已经学到了一个有用的新术语:“类型不经意”。 – 2010-01-28 17:29:23

大多数人坚持试图从他们最喜欢的语言内部元程序。由于模板元编程的原因,C++被视为典型例子。虽然它的作品,它是痛苦和笨拙的。我发现它告诉人们在Stroustrop将它添加到语言之后发现它具有图灵功能;尽管我怀疑他现在会抱怨它,但我认为他甚至不认为它会像他这样做。

但是大多数编程语言没有元编程功能。 (或者它们可能具有弱或笨拙的能力:)

解决此问题的方法是使用 program transformation tools以外的进行元编程。这些工具可以解析源代码,并对其进行任意转换(这就是元编程无论如何),然后吐出修改过的程序。

如果您有一个通用的程序转换系统,可以解析任意语言,那么您可以使用任何您喜欢的语言进行元编程。 请参阅我们的DMS Software Reengineering Toolkit,该工具对于C,C++,Java,C#,COBOL,PHP和许多其他编程语言具有健壮的前端,并且已用于所有这些元编程。

此方法非常有用,因为它提供了一种常规的方法论方法,可以为任何您想要操作的语言提供元编程方法。您不必等待语言设计人员和实施人员实施,也不必忍受他们可以想象或实际执行的限制,或者支付所需的所有反射数据的运行时间空间/时间价格以支持它。

尽管TM是图灵功能,程序转换比C++模板元编程更强大!原因是TM可以从模板生成任意代码,但不能修改非模板代码。如果你坚持,程序转换可以模拟TM,并且至少也是如此强大,但它也可以对非模板代码进行任意更改。因此,严格来说更强大。

就像TM一样,使用程序转换需要一些努力来学习和应用。但能够以任意方式操作程序似乎非常有用。 (我们已经对使用DMS的超大型C++应用程序进行了体系结构重组,但TM不能做到这一点)。

+0

另请参阅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

Papers by Abel Sinkovics