### 前言
? 在STL編程中,容器和算法是獨立設計的,即數據結構和算法是獨立設計的,連接容器和算法的橋梁就是迭代器了,迭代器使其獨立設計成為可能。Traits編程技術是STL中最重要的編程技術,Traits可以獲取一個類型的相關信息。在學習《STL源碼剖析》時,看到關于這方面的知識,在這期間查找了一些資料,下面是我對該技術的理解。
### Traits編程技術
? ? ?Traits可以獲取一個類型的相關信息,首先我們看下面的程序:
~~~
template <class T, class type>
void function(T t, type u) {
type temp;
// ... The rest work of function…
}
~~~
? ?在上面的程序中,我們怎么樣才能獲得已聲明變量temp的類型type呢?在模板中,模板參數推導機制可以解決這個問題,在下面程序中編譯器直到變量temp的類型為int:
~~~
template <class T, class type>
void function(T iter, type u)
{
type temp; // 通過模板參數推導獲得temp變量的類型
....
}
template <class T>
void func(T iter)
{
function(iter, *iter);
}
int main()
{
int i = 12;
func(&i)
}
~~~
? ? ? ?上面介紹的是獲得局部變量的類型,這個可以通過模板參數推導機制完成;如果我們要獲得函數返回值的類型時,該怎么處理呢?這個問題針對不同類型有不同的方法可以解決,類型型別:用戶自定義類型(如結構體,類)和內置類型(如整型,原生指針等)。
? 若我們要知道用戶自定義類型的函數返回值類型,我們可以使用內嵌型別技術就可以知道返回值的類型;看下面程序:
~~~
templates <class T>
struct Iterator
{
typedef T value_type;//內嵌型別聲明
...
};
template <class Iterator>
typename Iterator::value_type //返回值類型
GetValue(Iterator iter)
{
return *iter;
}
int main()
{
...
Iterator<int> ite(new int(9));
std::cout<<GetValue(ite)<<std::endl;
return 0;
}
~~~
? ? ? ?在用戶自定義類型中我們可以通過內嵌型別獲得返回值的類型,若不是用戶自定義的類型,而是內置類型時,例如是原生指針,這時候該怎么處理呢?因為原生指針不能內嵌型別聲明,所以內嵌型別在這里不適用。于是Traits技術就出現了。以下利用Traits技術也可以獲取用戶自定義類型的返回值類型。
~~~
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::value_type value_type;
...
};
template <class Iterator>
typename iterator_traits<Iterator>::value_type //返回值類型
GetValue(Iterator iter)
{
return *iter;
}
~~~
? ?以上這種方法對原生指針不可行,所以iterator_traits針對原生指針的一個版本就應運而生。下面是針對*Tp和const *Tp的版本,也稱為iterator_traits版本的偏特化。iterator_traits的偏特化版本解決了原生指針的問題。現在不管迭代器是自定義類模板, 還是原生指針(Tp*, const Tp*),struct iterator_traits都能萃取出正確的value type類型。
~~~
template <class Tp>
struct iterator_traits<Tp*> {
typedef Tp value_type;
...
};
template <class Tp>
struct iterator_traits<const Tp*> {
typedef Tp value_type;
...
};
~~~
? ? ? ?我們之所以要萃取(Traits)迭代器相關的類型,就是要把迭代器相關的類型用于聲明局部變量、用作函數的返回值等一系列行為。對于原生指針和point-to-const類型的指針,采用模板偏特化技術對其進行特殊處理。要使用Traits功能,則必須自行以內嵌型別定義的方式定義出相應型別。我們上面講解的只是迭代器其中一種類型value type,在迭代器中還有其他類型:
~~~
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; //迭代器引用之物
};
~~~
參考文獻:
[【1】](http://www.searchtb.com/2014/03/%E8%90%83%E5%8F%96traits%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF%E7%9A%84%E4%BB%8B%E7%BB%8D%E5%92%8C%E5%BA%94%E7%94%A8.html),[【2】](http://www.cppblog.com/nacci/archive/2005/11/03/911.aspx),[【3】](http://www.cnblogs.com/kanego/archive/2012/08/15/2639761.html),[【4】](http://www.codeproject.com/Articles/36530/An-Introduction-to-Iterator-Traits)
- 前言
- 空間配置器
- Traits編程技術
- STL源碼剖析——迭代器
- 全局函數construct(),destroy(),uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n()
- 序列容器之vector
- list容器的排序算法sort()
- 序列容器之list
- 序列容器之deque
- 容器配接器之stack
- 容器配接器之queue
- 容器配接器之priority_queue
- 最大堆heap
- 單向鏈表slist
- RB-Tree(紅黑樹)
- 關聯容器之set
- stl_pair.h學習
- 關聯容器之map
- 關聯容器之multiset
- 關聯容器之multimap
- 散列表hashtable
- stl_hash_fun.h學習
- 關聯容器之hash_set
- 關聯容器之hash_multiset
- 關聯容器之hash_map
- 關聯容器之hash_multimap
- 數值算法stl_numeric.h
- stl_relops.h學習
- 基本算法stl_algobase.h
- STL算法之set集合算法
- STL算法stl_algo.h
- STL算法之sort排序算法
- STL算法之find查找算法
- STL算法之merge合并算法
- STL算法之remove刪除算法
- STL算法之permutation排列組合
- STL函數對象