您的位置:首页 > 编程语言 > C语言/C++

C++的模板特化及STL中iterator_traits模板的偏特化

2012-01-12 11:34 477 查看
C++中有类模板和函数模板,它们的定义如下所示:

类模板:

template<class T1,class T2>
class C
{
//...
};
函数模板:

template<class T1,class T2>
void func(T1 p1,T2 p2)
{
//...
};
特化包括全特化和偏特化,全特化也叫简称特化,所以说特化的时候意思就是全特化。

特化就是对所有的模板参数指定一个特定的类型,偏特化就是对部分模板参数指定特定的类型。

类模板的特化:

template<class T1,class T2> //这里是类模板
class C
{
//...
};

template<>  //这里是对C的特化
class C<int,int>
{
//...
};


从语法上看,全特化的时候,template后面尖括号里面的模板参数列表必须是空的,表示该特化版本没有模板参数,全部都被特化了。

类模板的偏特化:

template<class T1,class T2> //这里是类模板
class C
{
//...
};

template <class T1>  //这里是对C的偏特化
class C<T1,int>
{
//...
};
从语法上看,偏特化的时候,template后面的尖括号里面的模板参数列表必须列出未特化的模板参数。同时在C后面要全部列出模板参数,同时指定特化的类型,比如指定int为T2的特化类型。

函数模板的特化:

template<class T1,class T2>  //这里是函数模板
void func(T1 p1,T2 p2)
{
//...
};

template <>  //这里是对函数模板的特化
void func(int p1,int p2)
{
//...
};


函数模板的偏特化:

函数模板不能进行偏特化!!!!!

STL中iterator_traits的偏特化

STL中的iterator_traits用来返回iterator中定义好的五种类型。其具体实现应该是(摘录自STL源码剖析)

template <class I>
struct iterator_traits
{
typedef typename I::iterator_category iterator_category;
typedef typename I::value_type value_type;
typedef typename I::differenct_type difference_type;
typedef typename I::pointer pointer;
typedef typename I::reference reference;
};
因为指针也是一种iterator,如果将指针作为模板参数,上面的定义就会失效。因此上面的模板必须对指针进行特化。特化的代码如下所示:

template <class T>  //对iterator_traits的偏特化
struct iterator_traits<T*>
{
typedef ... iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
}


template <class T>  //对iterator_traits的偏特化
struct iterator_traits<const T*>
{
typedef ... iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
}
为啥上面要对T* 和const T*进行偏特化,仅对I*进行偏特化不够么?

不够的,如果只对I*进行偏特化,iterator_traits<const int*>::value_type的类型就是const int。这一般不会是我们想要的,所以必须对const I*也进行特化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: