没有合适的资源?快使用搜索试试~ 我知道了~
C语言模板元编程与函数式语言的结合:EClean——一种嵌入式函数语言
理论计算机科学电子笔记238(2009)47-58www.elsevier.com/locate/entcsEClean -一种嵌入式函数语言A'd'amSipos1 而V i ktoo'riaZs'ok 2程序设计语言和语言学系匈牙利布达佩斯摘要C++模板元编程通常被认为是一种函数式语言,然而,现在元语法库并不是以函数式编程风格实现的。在本文中,我们讨论了编译时的图形重写引擎的基础上的功能语言清洁的属性。从函数式范例中引入的最重要的支柱是惰性求值策略。在引擎的帮助下可以将惰性函数式代码嵌入到C++程序中,并将其转换为模板元程序。我们通过例子,包括在有限列表中,提出了实现的懒惰评估策略。保留字:模板元编程,语言嵌入,函数式语言1引言模板元编程是C++编程中一个新兴的方向,用于在编译时执行算法。C++模板元程序和函数式编程之间的关系是众所周知的:模板元程序的大多数属性另一方面,C++有着强大的命令式编程传统(即来自C和Algol 68),并受到面向对象(Sim-ula 67)的影响。此外,C++模板的语法特别丑陋。因此,C++模板元程序通常很难阅读,也很难维护。理想情况下,编程语言接口必须与编写程序的范例相匹配。Meta是一个正在运行的项目,位于北京市Eo?tv?osLor?anddUn iver ity的规划和预算部。该项目的长期目标是为C++模板元程序定义和实现一个清晰且可维护的纯函数式接口。为此,模板元程序是用函数语言编写的,1 电子邮件地址:shp@inf.elte.hu2 电子邮件地址:zsv@inf.elte.hu1571-0661/© 2009由Elsevier B. V.出版,CC BY-NC-ND许可下开放获取。doi:10.1016/j.entcs.2009.05.00648×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47在C++程序中。这段代码由一个翻译器翻译成经典的模板元程序。结果是一个符合ANSI标准的原生C++程序[3]。Clean是一种纯粹的函数式懒惰编程语言[11]。在我们的方法中,我们探索清洁的主要功能,包括唯一性类型,高阶函数,以及强大的基于构造函数的语法生成数据结构。Clean还通过延迟评估支持无限数据结构我们将EClean定义为Clean语言的子集。EClean被用作编写模板元程序的嵌入式语言。Clean代码将由图重写引擎执行。解析器只识别Clean语言的一个子集,因为我们的目标是创建一种嵌入式语言,帮助程序员编写元程序,而不是实现一个完全功能的Clean编译器。该子集包括:• 递归,条件表达式• 函数定义• 基本内置类型(int、bool等)及其列表• 算术运算和比较在这篇文章中,我们概述了函数范式的最重要的属性,并评估了将它们转换为C++元语法的可能技术。Clean的图重写系统已被实现为一个C++模板元程序库。在引擎和相应的解析器的帮助下,EClean程序可以被翻译成C++模板元程序-作为这个库的客户端-并且可以以语义等价的方式进行评估。本文还实现了无限数据结构的延迟求值,并通过实例给出了计算结果。本文的组织如下:在第2节中,我们讨论了C++模板Meta编程,以及它与函数式编程的关系。懒惰的数据结构,评估,并在清洁功能语言的图形重写系统的模板元程序实现在第3节中描述。第4节详细讨论了EClean系统的转换过程,第5节讨论了未来的工作,第6节介绍了相关工作。2C++模板元编程模板是C++编程语言的关键元素[23]。它们使得可以通过类型参数化的数据结构和算法的实现成为可能,从而在编译时捕获抽象的共性,而不会在运行时失去性能[27]。模板元编程是一种生成式编程风格[6],利用C++模板功能在编译时执行算法。递归是通过强制编译器执行同一模板的一系列实例化来创建的。另一方面,也可以在模板专门化的帮助下创建编译时连接语句。有了这两个结构,TMP是图灵完备的[30],理论上它的表达能力相当于图灵机(以及大多数现代图灵机)。×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)4749编程语言)。元程序最重要的应用是概念检查的实现[33](在编译时测试某些类型属性),在编译时实现包含类型的数据结构(例如typical[2]),活动库的构造[7],以及许多其他。尽管TMP具有所有的优点,但由于缺乏编码标准和软件工具,TMP尚未在软件行业中广泛使用TMP的一个常见问题是冗长的语法和长代码。 像boost::mpl这样的库通过隐藏某些算法和容器的实现细节来帮助编程人员,但仍然有很大一部分编码留给了用户。由于缺乏标准-由于TMP的标准化接口,命名和编码约定因程序员而异,这导致了可理解性问题。模板元程序很多时候被认为是一种纯函数式语言程序。共同的属性包括引用透明性(元程序没有副作用)和缺少变量、循环和赋值。TMP最重要的功能属性之一是定义实体的不变性也就是说,如果我们定义了常量、枚举值、类型,它们的值或含义不能改变。元程序不包含赋值。代替它们的是递归和专门化,以实现循环,因为任何循环变量的值都不能改变。不变性– has a positive effect too: unwanted side effects do not occur in这两种编程范式之间的相似性需要更彻底的检查,因为元编程领域可以从更多函数技术的引入和库实现中受益在我们看来,有两种方法可以将函数接口集成到C++中:要么修改编译器以扩展语言本身,要么通过使用预处理器或宏创建库级解决方案。第一种方法可能更快、更简单、更灵活,但同时语言扩展也是不可取的在标准化的、广泛使用的语言如C++的情况下。 我们的方法是上述第二种方法。我们重新实现的清洁语言的图形重写引擎目标是在TMP中实现函数式语言的惰性属性。我们的方法有很多优点,比如:• 通过将用户编写的嵌入式代码与图形重写引擎分离,将Clean代码片段独立翻译为C++模板• 易于使用,因为引擎遵循[5]中定义的Clean语言的图形重写规则,所以翻译代码的语义尽可能接近程序员的意图。• 引入的库具有很高的可移植性,因为我们的解决方案只使用标准的C++元素。下面将通过详细的示例来呈现上述优点首先,我们描述实现的懒惰。50×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)473惰性评估策略由于延迟求值是函数式语言Clean最具特色的特性之一,因此本文主要研究延迟求值及其在C++模板元程序中的应用。为了展示惰性求值策略与模板元程序行为之间的相似性,我们在TMP中对纯函数式惰性语言Clean进行了建模干净的程序在编译器中由表达式图表示。该图在运行时分几个阶段自动重写。当开始符号右侧的主函数表达式被求值时,重写过程开始。Clean中的一个基本数据结构是列表。 在Clean中,列表被定义为链表[11]。在下文中,我们将列表描述为头元素和“尾”,因为它们在函数式程序中被模式匹配机制视为。 处理列表的这两部分的构造函数称为Cons。例如,列表[2,3,4]被写为Cons 2 Cons 3 Cons 4 Nil,其中Nil表示列表的末尾。惰性求值策略意味着 这种惰性使我们能够指定包含无限多个元素的列表,例如自然数列表:[1.] . 使用惰性列表的一个经典例子是Eratosthenes sieve算法,第一个任意多个素数。我们的运行示例使用EnumFrom。我们定义了EnumFrom构造函数来创建一个从某个数字开始的无限列表。名单[2] 因此可以写成EnumFrom 2(或[2..] ).当然,要获取列表的头元素,我们需要将此表达式重 写 为Cons 2 EnumFrom 3(或[2,EnumFrom 3]),也就是说,这是一个包含2和[3..]的列表。.下面我们将介绍一个简单的Clean程序,计算前10个素数。(The符号R1.. R6是行号)(R1)take0 xs=[](R2)taken [x,xs]=[x,take n-1 xs](R3)筛选[prime:rest]=[prime:sieve(filter primerest)](R4)过滤器p[h:tl]|hrem p == 0=filterp tl= [h:filter pt1](R5)过滤器p[] =[](R6)开始=取10(筛([2..]))Clean遵循左右最外层重写策略。第一个检查的表达式是Start表达式。Clean First尝试将重写规则之一应用于已检查的表达式,方法是将当前参数替换为规则的参数。如果不成功,则每个表达式(子表达式)的参数从左到右递归地检查如果任何子表达式可以重写,则计算返回到最外层的表达式。当没有规则适用于任何子表达式时,求值过程终止在我们的例子中,第一个被检查的表达式是(F1)。因为没有一条规则×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)4751左边取(F1)的形式,Clean检查(F1)中的第一个参数。 它是10,我们没有重写规则,这个表达式也没有子表达式。另一个参数sieve(EnumFrom2)也不能重写。 另一方面,参数EnumFrom 2等价于[2,EnumFrom3],这是在这种情况下发生的替换规则由于重写规则已经被应用,我们返回到最外面的表达式,现在是(F2)。再一次,这整个表达式,也不是它的第一个参数,第二个参数sieve [2,EnumFrom3]被检查。在这里可以应用(R3)规则,分别为prime=2和rest=EnumFrom 3。最外面的表达式现在采用(F4)的形式,这是我们返回的表达式。现在(R2)可以直接应用于n=10,x=2,xs=sieve(filter2 EnumFrom 3)。(F1)取10(筛[2..])(F2)取10(筛[2,[3..]])(F3)取10([2,筛(过滤器2 [3..])])(F4)[2,取9(筛(过滤器2 [3..]))](F5)[2,采取9 (筛[3,过滤器2 [4.])](F6)[2,采取9 【3、筛(过滤器3 (过滤器2[4..]))]](F7)[2,3,取8(筛(过滤器3(过滤器2 [4..])]...上面的例子很好地展示了应用的惰性评估策略。为了模拟懒惰函数式编程语言Clean的内部工作,重写算法使用TMP实现。重写是由我们的引擎执行的,在下一节中描述4图重写引擎下面我们将通过实例介绍将EClean程序转换为C++模板的方法。我们的EClean系统由两个主要部分组成:一个解析器-在本文中,我们将讨论后者的实施在编译混合C++程序时,EClean代码部分的评估通过以下步骤完成(参见图1):• C++预处理器在执行必要的头文件包含和宏替换时被调用。包含引擎和支持元程序的EClean库也在开始时导入• 原始源代码分为C++部分和EClean部分。• EClean的解析器将EClean部分转换为C++元语法代码片段。• 转换后的源代码被传递给C++编译器。• C++编译器在52×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47编译C++使用Start表达式,从而激活EClean引擎。• 该引擎模拟Clean• 当没有进一步的重写可以做,完成的表达式Fig. 1. EClean转换和编译过程4.1筛分程序下面我们将描述解析器执行的上述转换过程,以从第3节中编写的原始EClean函数代码创建元程序。EClean的表达式是表示按类型和typedefs。在这种方法中,我们示 例 中 的 Start 表 达 式 的 形 式 为 take mpl : : int 10> , sieve EnumFrommpl::int 2>。 这里take、sieve和EnumFrom都是具有相应签名的结构模板。图的重写过程可以用C++编译器的安装过程来模拟 当必须实例化具有某些参数的模板时,C++编译器从专门化中选择与该名称最匹配的模板。因此,规则可以用模板部分指定来实现。 每个部分特化都有一个内部类型定义,称为right,表示模式匹配规则的右侧与此同时,板名 字让 我 们 考 虑 下 面 的 例 子 , 它 描 述 了 筛 选 规 则 ( sieve[prime :rest]=[prime:sieve(filterprime rest)])。template class prime,class ys>struct sieve Cons prime,ys>>{typedefCons prime,sieve filter prime,ys> >> right;};标准C++编译器C++ECLEANECLEAN解析器ECLEAN翻译的ECLEAN代码在TMPECLEANTMP发动机eclean.h×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)4753筛模板有两个参数,prime和ys。此模板描述了我们的Clean示例中(R3)的工作方式 如果子表达式的形式为sieve< Cons< N,T>>,其中N和T是任意类型,则编译器将选择先前定义的sieve专门化作为子表达式的替代。请注意,即使N和T是一般类型,筛选模板也期望N是mpl::int,T是mpl::int类型的列表。然而,为了能够应用该重写规则,在重写过程期间需要精确匹配。例如,在(F1)评估期间,过程,在重写子表达式sieve [2..]时,将认为先前的sieve部分特化是适用的。.问题是,论证[2] (EnumFrom 2)与sieve偏特化参数列表不匹配,该列表需要Cons< N,T>形式的表达式,类型为N和T。 在编译期间,C++编译器将实例化类型sieve< EnumFrom< mpl::int <2>。但这是一个必须检测的模式匹配失败。因此,每个函数都必须为一般情况实现一个部分专门化,即没有一个同名的规则可以应用。引入了符号NoMatch,这标志着即使这个模板已经用一些参数xs实例化,这个论点没有适用的规则 NoMatch是一个简单的空类。模板类xs> structsieve{typedef NoMatchright;};前面介绍的过滤器函数在编译时挖掘x是否能被p整除,根据这个判断,可以选择这两个替代方案中的任何一个作为替代。filter的C++转换使用mpl::if进行编译时决策:template< int p,class x,classxs>struct filter boost::mpl::int_p>,Cons x,xs>>{typedef typedef boost::mpl::if_<类型等于::type,boost::mpl::int_0>>::type,filterp,xs>,Cons x,filter p,xs>>>::type right;};mpl::if构造在编译时做出决定。 第一种类型的PA-54×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47参数是if条件,在我们的例子中是一个等于模板,其内部类型typedef是一个mpl::bool。 根据bool的值,选择第一个或第二个参数。转换后的EnumFrom的工作方式与Clean类似:如果需要用EnumFrom重写,则会创建一个新列表,其中包含列表template class r>structEnumFrom{typedef Cons r,EnumFrom boost::mpl::int_r::value+1> right;};第3节的EClean示例的所有其他功能都可以翻译为使用前面的例子进行类比。在下文中,我们将介绍重写引擎识别EClean表达式,并使用前面的规则将其转换为TMP。4.2图重写引擎到目前为止,我们已经将Clean重写规则转换为C++模板,定义了它们的名称,参数列表(规则的部分特化)和它们的右侧。这些模板将用于创建表示表达式的类型,从而在编译时存储信息。这是第一个抽象层。下面我们将介绍下一个抽象级别,它使用这些存储的信息。这是由库的核心Eval结构的部分专门化完成的模板,用于评估给定的EClean表达式。由于专门化的参数本身就是一个模板(代表一个表达式),它自己的参数列表也必须被定义。由于这个约束,需要单独的实现来计算具有不同特性的表达式下面我们介绍Eval的一个版本,它只计算一个参数的表达式:1 模板类T1,模板类>类Expr>2 structEval Expr T1> > 3{4typedef类型5如果_c是_same typeExpr T1>::right,6NoMatch>::value,7typename8if_c!Eval T1>::second,9表达式T1>,10表达式类型评估T1>::结果>11>::type,12typeExpr T1>::right13>::typeresult; 14×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)475515staticconst bool second =16!(is_相同类型表达式T1>::right,NoMatch>::value&&17!Eval T1>::second);18};Eval的工作机制如下:Eval接受一个参数,一个带有一个参数T1的表达式Expr。类型变量T1可以是任何类型,例如int、整数列表或进一步的子表达式。 第13行中定义的返回类型结果包含新重写的子表达式或相同的输入表达式如果没有规则可以应用于表达式及其参数。当模板Expr没有参数T1的部分特化时,编译器会选择4.1节中描述的通用模板。第5行中的编译时if c用于确定是否发生了这种情况。• 如果是这种情况,则Expr T1>::right等于NoMatch。现在,另一个如果c被调用。在第8行T1中,第一个(也是唯一一个)参数被求值,递归调用Eval。布尔秒决定T1或它的任何参数是否可以重写。如果在这些子表达式中没有进行重写,Eval否则,返回类型是输入表达式,其T1参数替换为Eval T1>::result,这意味着T1本身或其参数之一已被重写。这种机制类似于类型推断。• 另一方面,如果找到匹配(ifc条件语句返回false值),则重写整个表达式,Eval返回转换后的表达式(第12行)。前面提到的布尔值second由每个Eval专门化定义(第15行)。它是表示表达式本身或其子表达式之一是否已重写的逻辑值。Eval对更多参数的实现与前面的示例非常相似,不同之处在于这些参数也必须递归地检查以进行重写。由于我们的表达式是作为类型存储的,因此在转换过程中,表达式的更改通过引入新类型来表示。转换的过程与Clean示例完全相同。以下类型被创建为右类型定义:take 10,sieve EnumFrom 2> take 10,sieve Cons 2,EnumFrom 3>take 10,Cons 2,sieve filter 2,EnumFrom 3> Cons 2,take 9,sieve filter 2>,EnumFrom 3> Cons 2,take 9,sieve 3,filter 2,EnumFrom 4> > Cons 2,take 9,Cons 3,sieve filter 3,EnumFrom 4>> Cons 2,3,take 8,filter 3,filter 2,EnumFrom4>...(请注意,在示例中,所有mpl::int前缀都从int值中省略56×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47为了方便阅读)。以上步骤演示了评估引擎的实现和工作机制发动机采取的最后一步将在下一小节中给出。4.3表达式的最终重写在阶乘示例中,我们已经看到,在实例化过程之后完成的表达式将是:times,times< mpl::int< 4>,times< mpl::int< 3>,times,mpl::int< 1>>>。通过简单的迭代,现在可以很容易地将列表成员mpl::int类型的值相互相乘,从而以int值的形式给出最终答案。5未来工作在我们的混合方法中,最有趣的问题之一是区分EClean可以单独处理的问题(例如,阶乘计算),以及那些需要模板元编程和编译器支持的。EClean解析器可以选择可以单独运行的函数调用,并在没有转换过程和C++编译器调用的情况下计算其结果。另一方面,对C++常量和类型的引用可以放在EClean代码中,并由EClean函数以回调风格使用。这将导致EClean和C++之间更大的灵活性和交互性。我们的EClean解析器的概念验证演示版本只处理int基本类型和整数列表。可以类似地使用其他内置类型。在未来,我们将包括对更多标量类型(bool,long等)的支持,除了已实现的Int和列表结构。用户定义的组合类型可能需要更复杂的解决方案。另一个有趣的方向是引入特殊的EClean类型,如表示C++类型的Type,表示C++函数甚至函数指针的Func解析器将扩展许多错误检测和恢复功能,这可以很容易地实现。有用的错误信息将帮助程序员使用EClean和编写元程序。EClean重写规则的优先级不能明确定义为与Clean相反。在EClean代码中,如果factorial1 = 1alternative在一般factorialn =n*factorial(n-1)下定义,则专用alternative永远不会匹配。然而,在模板形式中,由于模板实例化机制的性质,Factorial< mpl::int< 1> >替代项将匹配,即使定义在一般Factorial之下。 此时,解析器和引擎能够处理多个匹配。然而,这是一个重要而有趣的未来发展方向。×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47576相关工作C++中类似函数式语言的行为已经被研究过了。Functional C++(FC++)[12]是一个将函数式编程工具引入C++的库,包括currying,高阶函数和惰性数据类型。 然而,FC++是一个运行时库,我们的目标是在编译时利用函数式编程技术。mpl库是一个成熟的C++模板元程序库. Boost::mpl包含许多编译时数据结构、算法和函数式特性,如部分元函数应用程序和高阶元函数。然而,boost::mpl主要是为了遵循C++标准模板库的接口而设计的。没有明确支持在有限的数据结构中也是懒惰的。7结论在本文中,我们讨论了Meta Fun>项目,它增强了C++模板元程序的语法表达能力。EClean是通用函数式编程语言Clean的一个子集,它是一个嵌入式局域网.语言在C++宿主环境中编写元程序代码。Clean语言的图形重写系统已经实现为模板元程序库。函数代码片段在解析器的帮助下被翻译成经典的C++模板元程序。重写的元程序片段被传递到重写库。通过对无限数据结构的延迟求值验证了该方法的可行性由于图重写库只使用标准的C++语言功能,我们的解决方案不需要语言扩展,它是高度可移植的。引用[1] Abrahams,D.,A. Gurtovoy, ”C++ template metaprogramming, Concepts, Tools, and Techniques fromAddison-Wesley,2004年[2] Alexandrescu,A.,Addison-Wesley,2001年[3] ANSI/ISO C++委员会,[4] Bracha,G.,M. Odersky,D.吴文龙,“Java语言的通用性”,《面向对象程序设计:系统、语言和应用》,第183 - 200页,1998年[5] 布鲁斯,T. H、C. J. D. van Eekelen,M. O. van Leer,M. J. Plasmeijer,CLEAN:函数图重写语言。函数式编程语言和计算机体系结构会议论文集,第364 -384页,Springer-Verlag,1987[6] Czarnecki,K., 联合 W. Eisenecker,Addison-Wesley,2000年[7] Czarnecki,K., 联合 W. Ei s e necker,R. Gluück,D. 我们走吧,T。 L. 陈文生,通用程序设计与动态库,计算机科学讲义,第1766卷(1998),通用程序设计国际研讨会论文集,第25 -39页,1998年58×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)47[8] Eisenecker,U. W.,F. Blinn,K. Czarnecki,A Solution to the Constructor Problem of Mixin-BasedProgramming in C++,First C++ Template Programming Workshop,2000[9] Garc i a,R., J. Ja?vi,A. 我知道了,J。 Si ek,J. 王文生,《面向对象的通用程序设计方法》,第18届美国计算机学会通用程序设计会议115-134,2003年[10] Karlsson,B.,”Beyond the C++ Standard Library, A Introduction[11]Koopman,P.,R. Plasmeijer,M.van Eeekelen,S.Smetsers,[12] McNamara,B.,Y. Smaragdakis,C++中的函数式编程,ACM SIGPLAN国际函数式编程会议论文集,第118 -129页,2000年[13] Musser,D.R.,A. A. Stepanov,面向对象的通用库,软件实践和经验,27(7),页。623-642,1994年[14] Musser,D. R.,A. A. Stepanov,[15] McNamara,B.,Y. Smaragdakis,C++中的静态接口,第一次C++模板编程研讨会,2000年[16] Odersky,M.,王文生,《Java程序设计与实现》,北京:计算机科学出版社,1997[17] Plasmeijer河,M. van Eeekelen,[18] Siek,J.,[19] Siek,J.,A. Lumsdaine,概念检查:C++中的绑定参数多态性,第一个C++模板编程讲习班,2000年[20] Siek,J.,A.林文生,《通用编程的基本语言支持》,2005年ACM SIGPLAN编程语言设计与实现会议论文集,第73 -84页,2005年[21] 是的 ,“E. Sc. 《Thesis》,《EéotvéosLora'ndUniversity》,2006年[22] 是的 , N. 帕塔克岛,Z. 波尔科奥拉布,维。 Z s 'ok,Met a-TowardsaFunctinal-StyleInterfacorC++ Template Metaprograms,Proc. 函数式语言的实现,第489 -502页,2007年[23] Stroustrup,B.,”The C++ Programming Language Special Edition”, Addison-Wesley,[24] Stroustrup,B.,[25] Reis,G. D、B.张文龙,《C++的概念》,第33届ACM SIGPLAN-SIGACT程序设计语言原理研讨会论文集,第295 -308页,2006年[26] Unruh,E.,素数计算,ANSI X3 J16 -94-0075/ISO WG 21 -462。[27] Vandevoorde,D.,N. M. Josuttis:[28] Veldhuizen,T.,Using C++ Template Metaprograms,C++ Report vol. 7,no. 4,pp. 1995年第36-43号来文[29] Veldhuizen,T.,表达式模板,C++报告卷。号7第5页。1995年第26至31号来文[30] Veldhuizen,T.,C++模板是图灵完成的[31] 我是你的朋友, Z. Porkol′ab,Towardsat emplatentrospenlibrary,LecturreNotesonComputerScin ce3286(2004),第266 -282页,2004年[32] 我是你的朋友, Z. Porkol'ab,T. Kozsik,AnextensiontothesuccubtyperelionshipinC++,GPCE2003,计算机科学讲义2830(2003),第209 -227页,2003年[33] Boost概念检查http://www.boost.org/libs/concept_check/concept_check.htm[34] Boost元编程库http://www.boost.org/libs/mpl/doc/index.html[35] Boost预处理器库http://www.boost.org/libs/preprocessor/doc/index.html[36] Boost Static断言×。锡波斯河谷Zsók/理论计算机科学电子笔记238(2009)4759http://www.boost.org/regression-logs/cs-win32_metacomm/doc/html/boost_staticassert.html
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 4
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
- SPC统计方法基础知识.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功