stl中,traits程式設計技法得到了很大的應用,了解這個,才能一窺stl奧妙所在。
先將自己所理解的記錄如下:
traits技術可以用來獲得乙個 型別 的相關資訊的。 首先假如有以下乙個泛型的迭代器類,其中型別引數 t 為迭代器所指向的型別:
template
class myiterator
;當我們使用myiterator時,怎樣才能獲知它所指向的元素的型別呢?我們可以為這個類加入乙個內嵌型別,像這樣:
template
class myiterator
;這樣當我們使用myiterator型別時,可以通過 myiterator::value_type來獲得相應的myiterator所指向的型別。
現在我們來設計乙個演算法,使用這個資訊。
template
typename myiterator::value_type foo(myiteratori)
這裡我們定義了乙個函式foo,它的返回為為 引數i 所指向的型別,也就是t,那麼我們為什麼還要興師動眾的使用那個value_type呢? 那是因為,當我們希望修改foo函式,使它能夠適應所有型別的迭代器時,我們可以這樣寫:
template
//這裡的i可以是任意型別的迭代器
typename i::value_type foo(i i)
現在,任意定義了 value_type內嵌型別的迭代器都可以做為foo的引數了,並且foo的返回值的型別將與相應迭代器所指的元素的型別一致。至此一切問題似乎都已解決,我們並沒有使用任何特殊的技術。然而當考慮到以下情況時,新的問題便顯現出來了:
原 生指標也完全可以做為迭代器來使用,然而我們顯然沒有辦法為原生指標新增乙個value_type的內嵌型別,如此一來我們的foo()函式就不能適用原 生指標了,這不能不說是一大缺憾。那麼有什麼辦法可以解決這個問題呢? 此時便是我們的主角:型別資訊榨取機 traits 登場的時候了
....drum roll......
我們可以不直接使用myiterator的value_type,而是通過另乙個類來把這個資訊提取出來:
template
class traits
;這樣,我們可以通過 traits::value_type 來獲得myiterator的value_type,於是我們把foo函式改寫成:
template
//這裡的i可以是任意型別的迭代器
typename traits::value_type foo(i i)
然而,即使這樣,那個原生指標的問題仍然沒有解決,因為trait類一樣沒辦法獲得原生指標的相關資訊。於是我們祭出c++的又一件利器--偏特化(partial specialization):
template
class traits//注意 這裡針對原生指標進行了偏特化
;通過上面這個 traits的偏特化版本,我們陳述了這樣乙個事實:乙個 t* 型別的指標所指向的元素的型別為 t。
如此一來,我們的 foo函式就完全可以適用於原生指標了。比如:
int * p;
....
int i = foo(p);
traits會自動推導出 p 所指元素的型別為 int,從而foo正確返回。
過程:內嵌型別->traite類->模板偏特化=>可萃取原生指標的value type。
STL之traits程式設計技法
traits程式設計技法利用了 內嵌型別 的程式設計技巧與編譯器的template引數推導功能。下面主要看看利用traits程式設計技法實現的迭代器萃取機制。5種迭代器型別定義 struct input iterator tag struct output iterator tag struct f...
traits程式設計技法
iterator模式定義如下 提供一種方法,是指能夠依次序尋訪某個聚合物 容器 所含的各個元素,而又無需暴露該聚合物的內部表達。迭代器是一種智慧型指標 迭代器最重要的程式設計工作就是對opertor 和operator 進行過載工作。在演算法中運用迭代器時,很可能會用到其相應型別。利用functio...
Traits程式設計技法
照順序,這次應該是迭代器iterator的內容了,然而iterator涉及到乙個重要的技巧就是traits程式設計技法。在使用iterator時,可能需要知道它的相應型別,也就是iterator指向的變數的型別,在c c 語言中,如果要獲取乙個變數的大小可以使用sizeof 操作符。然而如果想要獲取...