在创建完成抽象操作的函数时,如:拷贝,反转和排序,你必须定义多个版本以便能处理每一种数据类型。以 max() 函数为例,它返回两个参数中的较大者:
double max(double first, double second); complex max(complex first, complex second); date max(date first, date second); //..该函数的其它版本 |
double max(double first, double second) { return first>second? first : second; } complex max(complex first, complex second) { return first>second? first : second; } date max(date first, date second) { return first>second? first : second; } |
这样不但重复劳动,容易出错,而且还带来很大的维护和调试工作量。更糟的是,即使你在程序中不使用某个版本,其代码仍然增加可执行文件的大小,大多数编译器将不会从可执行文件中删除未引用的函数。
用普通函数来实现抽象操作会迫使你定义多个函数实例,从而招致不小的维护工作和调试开销。解决办法是使用函数模板代替普通函数。
使用函数模板
函数模板解决了上述所有的问题。类型无关并且只在需要时自动实例化。本文下面将展示如何定义函数模板以便抽象通用操作,示范其使用方法并讨论优化技术。
第一步:定义
函数模板的声明是在关键字 template 后跟随一个或多个模板在尖括弧内的参数和原型。与普通函数相对,它通常是在一个转换单元里声明,而在另一个单元中定义,你可以在某个头文件中定义模板。例如:
// file max.h #ifndef MAX_INCLUDED #define MAX_INCLUDED template <class T> T max(T t1, T t2) { return (t1 > t2) ? t1 : t2; } #endif |
int n=10,m=16; int highest = max(n,m); // 产生 int 版本 std::complex<double> c1, c2; //.. 给 c1,c2 赋值 std::complex<double> higher=max(c1,c2); // complex 版本 |
template <class T> T max(const T& t1, const T& t2) { return (t1 > t2) ? t1 : t2; } |
unsigned int htonl (unsigned int hostlong); unsigned short htons (unsigned short hostshort); unsigned int ntohl (unsigned int netlong); unsigned short ntohs (unsigned short netshort); |
template <class T> T byte_reverse(T val); |
template <class T> T byte_reverse(T val) { // 将 val 作为字节流 unsigned char *p=reinterpret_cast<unsigned char*> (&val); std::reverse(p, p+sizeof(val)); return val; } |
int main() { int n=1; short k=1; __int64 j=2, i; int m=byte_reverse(n);// reverse int int z=byte_reverse(k);// reverse short k=byte_reverse(k); // un-reverse k i=byte_reverse(j); // reverse __int64 } |