最近在《C++ Templates》中看到了很多模板递归的例子,拿出其中一个做个总结,代码如下:
template<typename T>
class CompoundT {
public:
enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0};
typedef T BaseT;
typedef T BottomT;
};
template<typename T>
class CompoundT<T*> {
public:
enum { sPtrT = 1, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0};
typedef T BaseT;
typedef CompoundT<T> Temp;
typedef typename Temp::BottomT BottomT;
};
第一个模板是基本模板,第二个模板是第一个的特化,首先来说明一个这个模板的功能,大致来说,我们可以通过这个模板获知一些关于 模板参数 的 类型信息,比如我们有一个CompoundT<int**>,那么CompoundT<int**>::BaseT就是int*,CompoundT<int**>::BottomT就是int,现在我们就要看看我们是如何“计算”出BaseT、BottomT的值的:
1)首先,Compound<int**>更符合特化后的CompoundT模板,所以它会依照CompoundT<T*>来定义,在CompoundT<T*>中我们将BaseT设置成了T,由于这时T是int*,所以BaseT的值就是int*,接着我们遇到了这句话:
typedef CompoundT<T> Temp;
这句话等价于:
typedef CompoundT<int*> Temp;
这里出现的CompoundT<int*>同样更符合第二个模板特化,所以也会依照CompoundT<T*>来定义,这就形成了一个递归,在CompoundT<int*>中,当再次遇到这句话时:
typedef CompoundT<T> Temp;
这句话等价于:
typedef CompoundT<int> Temp;
这时我们需要定义CompoundT<int>,显然它更符合基本模板,所以就会依照CompoundT<T>来定义它,在CompoundT<T>中,BottomT被定义成了int,而且我们也没有再遇到其他的CompoundT递归定义,所以递归到此为止,此时CompoundT<int>中的Bottom被定义成了int,而CompoundT<int*>的BottomT被定义成了CompoundT<int>的BottomT,所以也变成了int,同样CompoundT<int**>的BottomT被定义成了CompoundT<int*>的BottomT,因此也成了int,所以递归返回以后,最终CompoundT<int**>的BottomT就是int。