热门IT资讯网

C++模板的特化与偏特化

发表于:2024-11-24 作者:热门IT资讯网编辑
编辑最后更新 2024年11月24日,C++模板的特化与偏特化最近在看STL的过程中,发现自己对于模板这里的知识有所生疏,因此今日将这部分内容再做整理,以备后忘。关于C++模板的概念这里不再赘述,默认读者已经具备基础知识。模板的特化先看一


C++模板的特化与偏特化


最近在看STL的过程中,发现自己对于模板这里的知识有所生疏,因此今日将这部分内容再做整理,以备后忘。


关于C++模板的概念这里不再赘述,默认读者已经具备基础知识。


模板的特化


先看一段代码:

#include using namespace std; template class TClass{public:     bool Equal(const T& arg, const T& arg1);}; template bool TClass::Equal(const T& arg, const T& arg1){     return (arg == arg1);} int main(){     TClass obj;     cout<

类里面就包括一个Equal方法,用来比较两个参数是否相等;上面的代码运行没有任何问题;但是,如果你传入一个float和一个double类型的参数,那么得到的结果有可能不是你想要的。所以,对于float或者double类型,我们需要进行特殊处理,处理如下:

#include using namespace std; template class Compare{public:     bool IsEqual(const T& arg, const T& arg1);}; // 已经不具有template的意思了,已经明确为float了template <>class Compare{public:     bool IsEqual(const float& arg, const float& arg1);}; // 已经不具有template的意思了,已经明确为double了template <>class Compare{public:     bool IsEqual(const double& arg, const double& arg1);}; template bool Compare::IsEqual(const T& arg, const T& arg1){     cout<<"Call Compare::IsEqual"<::IsEqual(const float& arg, const float& arg1){     cout<<"Call Compare::IsEqual"<::IsEqual(const double& arg, const double& arg1){     cout<<"Call Compare::IsEqual"< obj;     Compare obj1;     Compare obj2;     cout<

这样就实现了模板的特化,对于float和double的特化版本,甚至可以做一些与非特化的不一样的事情,这也是模板特化的初衷,使得特化的模板具有与非特化模板一同的行为。


模板偏特化

上面对模板的特化进行了总结。那模板的偏特化呢?所谓的偏特化是指提供另一份template定义式,而其本身仍为templatized;也就是说,针对template参数更进一步的条件限制所设计出来的一个特化版本。这种偏特化的应用在STL中是随处可见的。比如:

template struct iterator_traits {  typedef typename Iterator::iterator_category iterator_category;  typedef typename Iterator::value_type        value_type;  typedef typename Iterator::difference_type   difference_type;  typedef typename Iterator::pointer           pointer;  typedef typename Iterator::reference         reference;};template struct iterator_traits {  typedef random_access_iterator_tag iterator_category;  typedef T                          value_type;  typedef ptrdiff_t                  difference_type;  typedef T*                         pointer;  typedef T&                         reference;};template struct iterator_traits {  typedef random_access_iterator_tag iterator_category;  typedef T                          value_type;  typedef ptrdiff_t                  difference_type;  typedef const T*                   pointer;  typedef const T&                   reference;};

模板的偏特化与模板特化的区别在于,模板特化以后,实际上其本身已经不是templatized,而偏特化,仍然带有templatized。我们来看一个实际的例子:

#include using namespace std; // 一般化设计template class TestClass{public:        TestClass()        {                cout << "T1, T2" << endl;        }};// 针对普通指针的偏特化设计template class TestClass{public:        TestClass()        {                cout << "T1*, T2*" << endl;        }};// 针对const指针的偏特化设计template class TestClass{public:        TestClass()        {                cout << "const T1*, T2*" << endl;        }};int main(){    TestClass obj;                               //T1,T2    TestClass obj1;                        //T1*,T2*    TestClass obj2;     //const T1*,T2*     return 0;}

上面的代码就实现了模板的偏特化


特化与偏特化的调用顺序

对于模板、模板的特化和模板的偏特化都存在的情况下,编译器在编译阶段进行匹配时,是如何抉择的呢?从哲学的角度来说,应该先照顾最特殊的,然后才是次特殊的,最后才是最普通的。编译器进行抉择也是尊从的这个道理。从上面的例子中,我们也可以看的出来,这就就不再举例说明。


0