天天看點

c++類模闆的偏特化

隻有類模闆有偏特化,不能部分特例化函數模版,不過可以通過函數重載來實作類似功能。

所謂的偏特化是指提供另一份template定義式,而其本身仍為templatized;也就是說,針對template參數更進一步的條件限制所設計出來的一個特化版本。這種偏特化的應用在STL中是随處可見的。比如:

template <class _Iterator>
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;
};

// specialize for _Tp*
template <class _Tp>
struct iterator_traits<_Tp*> 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef _Tp*                        pointer;
     typedef _Tp&                        reference;
};

// specialize for const _Tp*
template <class _Tp>
struct iterator_traits<const _Tp*> 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef const _Tp*                  pointer;
     typedef const _Tp&                  reference;
};
           

與模闆特化的差別在于,模闆特化以後,實際上其本身已經不是templatized,而偏特化,仍然帶有templatized。我們來看一個實際的例子:

#include <iostream>
using namespace std;

// 一般化設計
template <class T, class T1>
class TestClass
{
public:
     TestClass()
     {
          cout<<"T, T1"<<endl;
     }
};

// 針對普通指針的偏特化設計
template <class T, class T1>
class TestClass<T*, T1*>
{
public:
     TestClass()
     {
          cout<<"T*, T1*"<<endl;
     }
};

// 針對const指針的偏特化設計
template <class T, class T1>
class TestClass<const T*, T1*>
{
public:
     TestClass()
     {
          cout<<"const T*, T1*"<<endl;
     }
};

int main()
{
     TestClass<int, char> obj;
     TestClass<int *, char *> obj1;
     TestClass<const int *, char *> obj2;

     return ;
}
           

結果:

c++類模闆的偏特化

特化與偏特化的調用順序:

對于模闆、模闆的特化和模闆的偏特化都存在的情況下,編譯器在編譯階段進行比對時,是如何抉擇的呢?從哲學的角度來說,應該先照顧最特殊的,然後才是次特殊的,最後才是最普通的。編譯器進行抉擇也是尊從的這個道理。

繼續閱讀