C++箴言:為類型信息使用特征類

字號:

STL 主要是由 containers(容器),iterators(迭代器)和 algorithms(算法)的 templates(模板)構(gòu)成的,但是也有幾個 utility templates(實用模板)。其中一個被稱為 advance。advance 將一個指定的 iterator(迭代器)移動一個指定的距離:
    template // move iter d units
    void advance(IterT& iter, DistT d); // forward; if d < 0,
    // move iter backward
    在概念上,advance 僅僅是在做 iter += d,但是 advance 不能這樣實現(xiàn),因為只有 random access iterators(隨機訪問迭代器)支持 += operation。不夠強力的 iterator(迭代器)類型不得不通過反復利用 ++ 或 -- d 次來實現(xiàn) advance。
    你不記得 STL iterator categories(迭代器種類)了嗎?沒問題,我們這就做一個簡單回顧。對應(yīng)于它們所支持的操作,共有五種 iterators(迭代器)。input iterators(輸入迭代器)只能向前移動,每次只能移動一步,只能讀它們指向的東西,而且只能讀一次。它們以一個輸入文件中的 read pointer(讀指針)為原型;C++ 庫中的 istream_iterators 就是這一種類的典型代表。output iterators(輸出迭代器)與此類似,只不過用于輸出:它們只能向前移動,每次只能移動一步,只能寫它們指向的東西,而且只能寫一次。它們以一個輸出文件中的 write pointer(寫指針)為原型;ostream_iterators 是這一種類的典型代表。這是兩個最不強力的 iterator categories(迭代器種類)。因為 input(輸入)和 output iterators(輸出迭代器)只能向前移動而且只能讀或者寫它們指向的地方最多一次,它們只適合 one-pass 運算。
    一個更強力一些的 iterator category(迭代器種類)是 forward iterators(前向迭代器)。這種 iterators(迭代器)能做 input(輸入)和 output iterators(輸出迭代器)可以做到的每一件事情,再加上它們可以讀或者寫它們指向的東西一次以上。這就使得它們可用于 multi-pass 運算。STL 沒有提供 singly linked list(單向鏈表),但某些庫提供了(通常被稱為 slist),而這種 containers(容器)的 iterators(迭代器)就是 forward iterators(前向迭代器)。TR1 的 hashed containers(哈希容器)的 iterators(迭代器)也可以屬于 forward category(前向迭代器)。
    bidirectional iterators(雙向迭代器)為 forward iterators(前向迭代器)加上了和向前一樣的向后移動的能力。STL 的 list 的 iterators(迭代器)屬于這一種類,set,multiset,map 和 multimap 的 iterators(迭代器)也一樣。
    力的 iterator category(迭代器種類)是 random access iterators(隨機訪問迭代器)。這種 iterators(迭代器)為 bidirectional iterators(雙向迭代器)加上了 "iterator arithmetic"(“迭代器運算”)的能力,也就是說,在常量時間里向前或者向后跳轉(zhuǎn)一個任意的距離。這樣的運算類似于指針運算,這并不會讓人感到驚訝,因為 random access iterators(隨機訪問迭代器)就是以 built-in pointers(內(nèi)建指針)為原型的,而 built-in pointers(內(nèi)建指針)可以和 random access iterators(隨機訪問迭代器)有同樣的行為。vector,deque 和 string 的 iterators(迭代器)是 random access iterators(隨機訪問迭代器)。
    對于五種 iterator categories(迭代器種類)中的每一種,C++ 都有一個用于識別它的 "tag struct"(“標簽結(jié)構(gòu)體”)在標準庫中:
    struct input_iterator_tag {};
    struct output_iterator_tag {};
    struct forward_iterator_tag: public input_iterator_tag {};
    struct bidirectional_iterator_tag: public forward_iterator_tag {};
    struct random_access_iterator_tag: public bidirectional_iterator_tag {};
    這些結(jié)構(gòu)體之間的 inheritance relationships(繼承關(guān)系)是正當?shù)?is-a 關(guān)系:所有的 forward iterators(前向迭代器)也是 input iterators(輸入迭代器),等等,這都是成立的。我們不久就會看到這個 inheritance(繼承)的功用。