• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Effective STL 條款18

    發表于:2007-07-01來源:作者:點擊數: 標簽:
    Item18避免使用vectorbool 做為一個STL容器,vectorbool有兩個問題.第一,它不是一個真正STL容器,第二,它并不保存bool類型. 除此以外,并沒有太多東西與本節題目有關(譯注,還不夠多嗎) 一個東西不能成為一個STL容器,只因為會有人說它是一個(譯注,:( )

    Item18避免使用vector<bool>
     
    做為一個STL容器,vector<bool>有兩個問題.第一,它不是一個真正STL容器,第二,它并不保存bool類型.
    除此以外,并沒有太多東西與本節題目有關(譯注,還不夠多嗎)

    一個東西不能成為一個STL容器,只因為會有人說它是一個(譯注,:( ).一個東西要成為STL容器,必須滿足所有
    列于C++標準23.1節的容器要求.在這些要求中,有這樣一條:如果C是一個T類型元素容器,并且C支持operator[]
    那么以下代碼必須能夠編譯:

    T *p = &c[0]; // initialize a T* with the address
           // of whatever operator[] returns

    換句話說,如果你使用operator[]來得到Container<T>中的一個T對象,你可以對它取地址從而得到一個指針.
    (假設T沒有重載opeartor&.譯注:原句為This assumes that T hasn´t perversely overloaded operators.
    從意譯)因此,如果vector<bool>可能成為容器,那么,這些代碼必須編譯通過:

    vector<bool> v;
    bool *pb = &v[0]; // initialize a bool* with the address of
                      // what vector<bool>::operator[] returns

    但是它不能編譯.不能的原因是vector<bool>是一個偽容器(pseudo-container),它并不保存真正的bool,而是
    打包bool以節省空間.在一個典型的實現中,每一個"bool"保存在"vector"中都是一個"bit",8-bit的一個字節
    將保存8個bool.從內部來看,vector<bool>使用了與位域(bitfields)相同的思想來表示需要保存的bool值.

    與bool值相似,位域也只有兩個值,但有它倆之間有一個重要的不同:可以創建指向真正的bool型的指針,但指
    向單獨一位的指針卻非法.

    考慮到指向單獨一位的指針非法,這為vector<bool>的設計擺出了難題.因為vector<T>::operator[]的返回值
    是T&類型.如果vector<bool>保存真正的bool值,這不成問題.但是因為它沒有,vector<bool>::operator[]
    (譯注:原文為()疑誤)不知如何返回一位的引用,并不存在這樣的東西.

    為了解決它,vector<boo>::operator[]返回一個對象,其行為類似于位的引用,也稱為代理對象.(僅使用STL,
    你并不需要明白什么是代理.它是一項值得了解的C++技術.關于代理的信息,參考More Effective C++的Item30
    還有Gamma等人(就是GoF)的設計模式一書中Proxy章節).深入本質來看,vector<bool>可能類似于這樣:

     template <typename Allocator>
     vector<bool, Allocator> {
     public:
     class reference {...}; // class to generate proxies for
        // references to individual bits
     reference operator[](size_type n); // operator[] returns a proxy
     …
     }

    現在,這些代碼不能編譯的原因就很明顯了.

    vector<bool> v;
    bool *pb = &v[0]; // error! the expression on tne right is
        // of type vector<bool>::reference*,
        // not bool*

    因為它不能編譯,所以vector<boo>不滿足STL容器的需要.vector<bool>在標準中,它也滿足了大多數STL容器的需要
    ,但是它還不夠好.你寫的關STL容器的代碼越多,會越深刻地認識到這一點.當一天來到時,我保證,當你會寫
    出一個模板,它只在可以取得容器元素的地址時才工作.到那時,你將突然明白容器和幾乎是一容器之間的區別.

    也許你想知道為什么vector<bool>存在于標準中,而它并不是一個容器.答案是與一個貴族失敗的實驗有關.但讓我們
    推遲一下討論,我有一個更緊迫的問題.如果vector<bool>應避免,因為它不是一個容器,那當需要一個vector<bool>時
    應使用什么?

    標準庫提供了兩個代替物,它們滿足幾乎所有需要.第一個是deque<bool>.deque提供幾乎所有vector提供的(唯一值得
    注意的是reserve和capacity),并且deque<bool>是一個STL容器,它保存真正的bool值.當然,deque底層的內存不連續.
    所以不能傳遞deque<bool>中的數據給一個期望得到bool數組的C API(參見Item 16),但是vector<bool>也不能作這一點
    因為沒用可移植的方法取得vector<bool>中的數據.(Item16中的技術不能在vector<boo>上編譯.因為這種技術依賴于
    能夠取得容器元素的指針.我提到過vector<bool>中不保存bool值吧?)

    第二個vector<bool>的代替物是bitset.bitset不是一個STL容器,但它是C++標準庫的一部分.與STL容器不同,它的大小
    (元素總數)在編譯期固定.因此,它不支持插入和刪除元素,近一步,因為它不是一個STL容器,它也不支持iterator.
    與vector<bool>類似,它使用一個壓縮的表示法,使得每個值只占用一位.它提供vector<bool>的特殊成員函數,還包含
    一系列操作位集(collection of bits)的特殊成員函數.如果不在乎沒有迭代器和動態大小,那么bitset也許正合你意.

    現在我們來討論那個貴族的失敗的實驗,正是它將非STL容器的vector<bool>留在了標準庫中.我早先提到代碼對象在C++
    程序設計中十分有用.C++標準委員會的成員當然也意識到了,他們決定開發vector<bool>做為一個演示.它說明STL如何
    支持包含通過代理訪問元素的容器.一但這個例子出現在標準中,而且它說明得很詳細,開發者將有一個參考,來實現自己
    的基于代理的容器.

    可是,最終他們發現,不可能創建一種基于代理的容器,它滿足所有STL容器的需要.因為某種原因,他們失敗了,而開發中
    的這個例子留在了標準中.也許有人將探尋vector<bool>存在的原因,但現實地說,這不影響什么.重要的是:vector<bool>
    不滿足STL容器的需要;你最好不要使用它;deque<bool>和bitset是基本能滿足你的需要vector<bool>代替品.


    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>