1 模板元编程(TMP)技术
在C++程序设计语言中,模板元编程是实现代码重用的一种重要机制。下面首先对模板元编程技术进行介绍,然后给出TADA方法中需要使用的几个基本的模板元程序。
1.1 模板元编程简介
模板可以将类型定义为参数,以提高代码的可重用性。模板包括类模板和函数模板等。函数模板与模板函数的区别可以类比于类与对象的区别:函数模板是模板的定义;而模板函数是函数模板的实例,具有程序代码,占用内存空间。当编译系统发现了函数模板一个对应的函数调用后,根据实参的类型来确认是否匹配函数模板中对应的形参,然后生成一个重载函数,称该重载函数为模板函数。类似地,在声明了一个类模板后,也可以创建类模板的实例一模板类。
类模板的一般形式如下:
template
class类名{
//类定义…
};
C++模板系统能够通过模板的特化、偏特化实现逻辑判断,并能通过模板递归实现循环,构成了一个图灵完全的二级语言。使用这种二级语言进行编程叫作C++模板元编程(Template Meta Programming,TMP)。模板元编程的驱动力是模板的递归实例化。
下面给出C++模板元编程的一个示例。
首先定义一个类模板,通过该类模板可实现在编译期间计算4的任意次方。如下所示:
通过下面的程序来使用该模板。
程序Test.cpp执行完后,会正确输出4的7次方的值,该数值是C++编译器在编译模板元程序时递归计算得到。由于模板元程序完全在编译期间执行,相当于对编译器功能进行扩充,因而利用这种程序进行量纲检测具有良好的可行性。
1.2 基本模板元程序
下面给出TADA方法中需要使用的几个基本的模板元程序。
(1)静态判断
语法:StaticlF<cond,T1,T2>::ResultType
语义:当cond为真时,ResuhType为T1,否则ResuhType为T2。
(2)静态断言
语义:当cond为真时什么也不做,否则产生一个编译期错误(UnitError没有定义,或void函数不应该有返回值)。
(3)静态绝对值
语义:递归的使用辗转相除法在编译期间求出a与b的最大公约数,其中a与b为int类型。
2 TADA量纲检测方法
TADA量纲检测方法需要涉及到单位和量纲的表示、计算、标注以及数学运算函数的量纲包装等各个组成步骤,下面将依次对其进行介绍。
2.1 单位和量纲的表示
在Osprey方法中,量纲是用一个长度为7的向量表示的,每个分量对应一个SI标准量纲。TADA方法中也采用了这种方式。为了简化阐述,本文只讨论长度、重量、时间这三种量纲,其SI单位分别为米、千克和秒(TADA方法可直接推广到其他各种量纲)。由于TMP程序的特殊性,它并没有数组或向量的支持,也不能使用浮点数据(使用浮点数表示量纲也会带来不精确性),量纲在TMP程序中的表示形式有所不同:用u11,u12,u21,u22,u31,u32之类的整型量分别表示,并辅以ratio表示同量纲、不同单位之间的比值,如分钟和秒的比值为60。
TADA方法可静态地建立如下常用单位:
模板元程序在计算公式的时候需要推导出新的量纲,例如在计算的时候,编译器应该能根据等号右边的公式计算出它的量纲,并与e的量纲进行比较判别。TADA方法的量纲是用分数形式表示的,在每次量纲计算之后都需要进行分数的约分处理,才能进行相等性判断,因而TADA方法可用如下的方式处理新生成单位,如下所示。