原文:http://blog.youkuaiyun.com/qaz19870418/archive/2009/06/14/4269189.aspx
从今天开始来学习一下《C++ template》,学习c++ template的动机来自于自己在实现数据结构中的类的时候所遇到的困难。虽然以前在谭浩强老师所编写的《C++程序设计》一书中学过一点c++模板的的知识,但是那本书中讲的关于模板的知识是在是太少了,等到用的时候才发现好多东西不知道怎么用模板的只是知识来解决。
1.为什么要引入模板机制?
我们知道,代码重用(code reuse)是软件工程的重要目的之一,代码重用是减少代码键入数量,缩短软件开发时间的一项非常有效地手段,而模板机制的引入正是为了能够更好的实现代码重用。
在c语言中,我们可以通过宏(macro)来实现代码的重用。例如有以下三个函数:
int max(int a, int b)
{
return a>b?a:b;
}
float max(float a, float b)
{
return a>b?a:b;
}
float max(float a, float b)
{
return a>b?a:b;
}
double max(double a, double b)
{
return a>b?a:b;
}
这三个函数的功能是一样的,都是求a,b中较大的数,通过观察我们可以发现这三个函数除了数据的类型不一样外,其他的部分一模一样。然而我们却用了三个函数来实现这一功能,这显然不符合代码重用的原则,为此,我们可以将以上三个函数用宏实现,如下:
#define MAX(a, b) ( (a)>(b)?(a):(b))
MAX(2, 3); //计算结果为3
MAX(1.2, 3.5); //计算结果为3.5
MAX(1, 2.4); //结果为2.4
MAX(2.4, 1); //结果为2.4
这样一来就大大简化了代码,但是这样却引入了一个问题。因为宏是类型不安全的,在编译器在预处理的时候只是进行简单的替换,而不会进行类型检查,降低了程序的安全性。
为了保留宏的简洁性以及消除其不安全性,c++中引入了模板,它既有宏的简洁方便的特点,又具有安全性。能够很好的支持代码重用。上面这个例子用模版实现如下:
template
inline T const & max(T const& a, T const& b)
{
return a>b?a:b;
}
max(2, 3); //计算结果为3
max (1.2, 3.5); //计算结果为3.5
max (1, 2.4); // ERROR: first T is int, second T is double
max(2.4, 1); // ERROR: first T is double, second T is int
我们看到当我们使用max(1, 2.4)时,编译器会提示错误,原因是我们只申明了一个模版参数T, 但是在这个调用中第一个T为int, 第二个T为double,编译器不知道到底该选用哪一个来替代T,所以提示错误。
从这里我们知道了模板与宏的一个不同之处,那就是模板不支持默认的数据类型转换,而宏支持默认的数据类型转换。这样模板就能够让程序按照我们的意愿来执行,以免发生不可预料的结果。
那么,如果我们需要用函数模版max来比较1和2.4,我们该如何做呢?
类型重复,交错
我们有三种方法来解决这个问题:
方法一,将二者的类型转换成一致:
max(static_cast(1), 2.4); // OK,结果为2.4
max(2.4, static_cast(1)); OK,结果为2.4
方法二,显式地指定类型T:
max(1, 2.4); //OK,结果为2.4
max(2.4, 1); //OK,结果为2.4
方法三,使用两个模版参数:
template
inline T2 max (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
max(1, 2.4); //OK,结果为2.4
max(2.4, 1); //ERROR,返回类型不匹配
我们看到,这里max(2.4, 1)编译出现错误,错误的原因是由于返回类型不匹配。那么我们该如何解决这个问题呢?
我们可以这样考虑,我们可以增加一个模版参数,用来指定模版函数的返回值,具体形式如下:
template
inline RT max (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
max(1, 2.4); //OK,返回2.4
max(2.4, 1); //OK,返回2.4
这样虽然问题解决了,但是通过max(1, 2.4);这种方式来调用显得非常复杂,我们对以上函数稍微改动一下,就可以简化调用的形式:
template
inline RT max (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
max(1, 2.4); //OK,返回2.4
max(1, 2.4); //OK,与max(1, 2.4); 等价
max< double>(2.4, 1); //OK,返回2.4
max(2.4, 1); //OK,与max< double>(2.4, 1);等价
很显然通过max(1, 2.4);和max< double>(2.4, 1);来调用要简单的多。这样既解决了代码重用,又简化了调用接口,方便编程。
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/qaz19870418/archive/2009/06/14/4269189.aspx