避免使用vector<bool>

來源:互聯網
上載者:User

標籤:vector   deque   bitset   



作為一個STL容器,vector<bool>只有兩點不對。首先,它不是一個STL容器。其次,它並不儲存bool。除此之外,一切正常。

一個對象要成為容器,就必須滿足C++標準中列出的所有條件,其中一個條件是,如果c是包含對象T的容器,而且c支援operator[],那麼下面的代碼必須能夠被編譯:

T *p = &c[0];

換句話說,如果用operator[]取得了container<T>中的一個T對象,那麼就可以通過取它的地址得到一個指向該對象的指標。所以,如果vector<bool>是一個容器,那麼下面這段代碼必須可以被編譯:

vector<bool> v;

bool *pb = &v[0];

但是它不能編譯。不能編譯的原因是,vector<bool>是一個假的容器,它並不真的儲存bool,相反,為了節省空間的,它儲存的是bool的緊湊表示。在一個典型的實現中,儲存在“vector”中的每個“bool”僅佔一個二進位位,一個8位的位元組可容納8個“bool”。在內部,vector<bool>使用了與位域一樣的思想,來表示它所儲存的那些bool;實際上它只是假裝儲存了這些bool。

位域與bool相似,它只能表示兩個可能的值,但是在bool和看似bool的位域之間有一個很重要的區別:我們可以建立一個指向bool的指標,而指向單個位的指標則是不允許的。指向單個位的引用也是被禁止的,這使得在設計vector<bool>的介面時產生了一個問題,因為vector<T>::operator[]的返回值應該是T&.如果vector<bool>中所儲存的確實是bool,那麼這就不是問題。但由於實際上並非如此,所以vector<bool>::operator[]需要返回一個指向一個單個位的引用,而這樣的引用並不存在。

當我們需要vector<bool>時,我們有兩種選擇可以做:

  1. 用deque<bool>。deque幾乎提供了vector所提供的一切(可以看到的省略只有reserve和capacity),但deque<bool>是一個STL容器,而且它確實儲存bool。當然,deque中元素的記憶體不是連續的,所以你不能把deque<bool>中的資料傳遞給一個期望bool數組的C API,但對於vector<bool>,我們也不能這麼做,因為沒有一種可移植的方法能夠得到vector<bool>中的資料。

  2. 選擇bitset。bitset不是STL容器,但它是標準C++庫的一部分。與STL容器不同的是,它的大小(即元素的個數)在編譯時間就確定了,所以它不支援插入和刪除元素。而且,因為它不是一個STL容器,所以它不支援迭代器。但是,與vector<bool>一樣,它使用了一種緊湊表示,只為所包含的每個值提供一個空間。它提供了vector<bool>特有的flip成員函數,以及其它一些特有的、對位的集合有意義的成員函數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.