首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++模板的替代方案?

C++模板的替代方案?
EN

Stack Overflow用户
提问于 2010-01-28 09:04:31
回答 5查看 6.3K关注 0票数 6

我认为元编程非常非常酷。特别是,我喜欢lisp宏。

然而,我认为C++模板很糟糕,因为:

  1. 它们减慢了编译时间(即使是预编译头文件,如果你包括任何STL的东西,最终都会有50MB的大小)。
  2. 它们提供了可怕的编译器/语法错误,这些错误最初并不是为复杂的元编程而设计的(为质数生成编译器错误/显示模板是图灵完成在过去是一件大事)。

话虽如此,对于C++元编程,有没有合适的替代方案呢?就像这样

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

编辑:

我的思路是“自定义代码生成脚本”。我只是想知道外面有没有很好的一组。

EN

回答 5

Stack Overflow用户

发布于 2010-01-28 09:12:37

我不确定这是否应该是我想要的,我已经使用代码生成器来生成C++代码。尤其是蟒豹。你可以直接在你的C++代码中嵌入python代码,然后遍历cheetah preprocessor.it,这样就可以比使用模板或者C++预处理器更容易地完成相当复杂的计算,而且你还可以得到所有的python库和扩展。另一方面,它使调试变得更加困难,如果发生wrong.if,你感兴趣的话,我可以提供一些示例和Emacs模式来编辑cheetah C++程序。

如果您需要一些不太强大的工具,并且只想停留在C++ C中,那么可以看看boost预处理器here。这需要一些时间来适应它,但当涉及到重复的代码时,可以让生活变得非常容易。

好的,我正在粘贴猎豹的例子,给我几分钟时间:

代码语言:javascript
复制
#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 ...之后)

代码语言:javascript
复制
#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++代码

以%开头的行被cheetah预处理器解释为python语句。/是猎豹注释。默认使用#作为python语句,但我更改了它们,以避免与C预处理器指令冲突。必须使用%end来终止python块。在C++代码中,以$开头的变量将被替换为python变量。

你想要使用boost预处理器的例子吗?

票数 7
EN

Stack Overflow用户

发布于 2010-02-27 02:43:37

大多数人坚持从他们最喜欢的语言内部进行元编程。由于模板元编程,C++被认为是典型的例子。虽然它有效,但它是痛苦和笨拙的。我发现在Stroustrop将它添加到语言中之后,它告诉人们它是Turing能力的;我认为甚至他都没有预料到它会变成他所做的那样,尽管我怀疑他现在会抱怨它。

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

解决这个问题的一种方法是在语言之外使用 program transformation tools进行元编程。这样的工具可以解析源代码,并对其执行任意转换(这就是元编程所做的),然后生成修改后的程序。

如果你有一个通用的程序转换系统,可以解析任意语言,那么你可以在任何你喜欢的语言上进行元编程。关于这样一个工具,请参阅我们的DMS Software Reengineering Toolkit,它有C、C++ (甚至是C++17)、Java、C#、COBOL和许多其他编程语言的健壮前端,并且已经在所有这些语言上用于元编程。

这种方法很有用,因为它提供了一种常规的、方法论的方法来为您想要操纵的任何语言提供元编程方法。而且,您不必等待语言设计者和实现者实现,也不必忍受他们所能想象或实际实现的限制,也不必为支持它所需的所有反射数据支付运行时空间/时间代价。

和程序转换比C++模板元编程更强大,尽管TM具有图灵功能!原因是TM可以从模板生成任意代码,但不能修改非模板代码。如果您坚持的话,程序转换可以模拟TM,因此至少同样强大,但它也可以对非模板代码执行任意更改。因此,严格地说,更强大。

像TM一样,使用程序转换需要花费一些精力来学习和应用。但是,能够以任意方式操纵程序似乎非常有用。

(我们已经使用DMS对非常大的C++应用程序进行了架构重构。TM根本无法做到这一点)。

票数 4
EN

Stack Overflow用户

发布于 2010-01-28 09:19:52

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

您还应该了解Linux内核是如何处理链表的。

Linux Kernel Linked List Explained

基本思想是,不是将类型嵌入到某个结构中(例如,对于典型的列表实现,使用next和prev指针),而是将内核列表结构嵌入到结构中……有点曲解,但看看这篇文章...在我看到这个之前,我从来没有想过类型安全泛型在C中是可能的……

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2151597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档