STL中,traits程式設計技法 模板

2021-07-13 19:47:36 字數 1649 閱讀 7815



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 操作符。然而如果想要獲取...