traits編程技法大量運用於STL實現中。通過它在一定程度上彌補了C++不是強型別語言的遺憾,增強了C++關於型別認證方面的能力。
traits編程技法是利用“”的編程技法和實現的。
iterator_traits
1.對於class type要求其“內嵌型別”
要求與STL兼容的容器,其迭代器必須定義一下五種型別:
iterator_category 迭代器類型
value_type 迭代器所指對象類型
difference_type 迭代器間的距離類型
pointer
reference
2.對於非class type(如:原生指針)需要使用template partial specialization(偏特化)
template < _Iterator> template < _Tp> iterator_traits<_Tp*> typedef _Tp* typedef _Tp& template < _Tp> iterator_traits< _Tp*> typedef _Tp* typedef _Tp& };
iterator中為什麼要引入traits機制?
提高效率
對效率的至極追求貫穿整個STL設計,traits機制的引入是為了實現 以提高效率。
例如 advance():
template < _InputIter, _Distance> inline __advance(_InputIter& (__n--) ++ template < _BidirectionalIterator, _Distance> inline __advance(_BidirectionalIterator& (__n >= (__n--) ++ (__n++) -- template < _RandomAccessIterator, _Distance> inline __advance(_RandomAccessIterator& __i += template < _InputIterator, _Distance> inline advance(_InputIterator& }
SGI STL中迭代器之外的 __type_traits
STL只對迭代器進行了traits規范,制定類iterator_traits。SGI 把這種規范擴大到類迭代器之外,也就是__type_traits(__前綴表示是SGI 內部使用的,不在STL規范內)。
iterator_traits負責萃取iterator特性,而__type_traits則負責萃取一下五種型別(type)特性:
has_trivial_default_constructor 是否有平凡的默認構造函數
has_trivial_copy_constructor 是否有平凡的拷貝構造函數
has_trivial_assignment_operator 是否有平凡的分配操作
has_trivial_destructor 是否有平凡的析構函數
is_POD_type 是否為POD類型(POD:Plain Old Data)
如果class內含指針成員,並對它進行內存動態分配,那麼這個class就需要實現自己的 non-trivial-xxx。
上述特性應該響應我們“真”或“假”,但卻不能是bool值,因為我們要利用其響應來進行參數推導,而編譯器只有面對class object形式的參數時才能進行參數推導,因此響應應該是帶有“真”“假”性質的不同類。SGI STL中如下定義:
1 struct __true_type { 2 }; 3 4 struct __false_type { 5 };
template < _Tp> };
為保守起見都定義為__false_type
在SGI STL的Type_traits.h中對C++ 內建的bool/char/signed char/unsigned char等標記為__true_type。
為什麼要引入__type_triats?
答案還是提高效率
對於標記為__true_type的型別,對其對象進行構造/析構/拷貝/賦值等操作時就可以采用最有效率的措施。(如:不必調用高層次的constructor/destructor,而采用內存直接處理操作malloc()/memcpy()等)