作為一個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>時,我們有兩種選擇能夠做:
-
用deque<bool>。deque差點兒提供了vector所提供的一切(能夠看到的省略僅僅有reserve和capacity),但deque<bool>是一個STL容器,並且它確實存儲bool。當然,deque中元素的內存不是連續的,所以你不能把deque<bool>中的數據傳遞給一個期望bool數組的C API,但對於vector<bool>,我們也不能這么做,由於沒有一種可移植的方法可以得到vector<bool>中的數據。
-
選擇bitset。bitset不是STL容器,但它是標准C++庫的一部分。
與STL容器不同的是,它的大小(即元素的個數)在編譯時就確定了,所以它不支持插入和刪除元素。並且,由於它不是一個STL容器。所以它不支持迭代器。可是。與vector<bool>一樣。它使用了一種緊湊表示。僅僅為所包括的每一個值提供一個空間。它提供了vector<bool>特有的flip成員函數,以及其他一些特有的、對位的集合有意義的成員函數。