隻有類模闆有偏特化,不能部分特例化函數模版,不過可以通過函數重載來實作類似功能。
所謂的偏特化是指提供另一份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 ;
}
結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICdzFWRoRXdvN1LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9smeNlXWU1UenpXTmZEWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN2kDNxITM3EDMzITM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
特化與偏特化的調用順序:
對于模闆、模闆的特化和模闆的偏特化都存在的情況下,編譯器在編譯階段進行比對時,是如何抉擇的呢?從哲學的角度來說,應該先照顧最特殊的,然後才是次特殊的,最後才是最普通的。編譯器進行抉擇也是尊從的這個道理。