簡體   English   中英

我如何檢查矢量 <bool> 實際上是位向量而不是字節的向量?

[英]How do I check if vector<bool> is actually a vector of bits and not bytes?

我需要存儲一個動態的位數組。
vector <bool>上的C ++參考頁面包含以下信息:

存儲不一定是bool值的數組,但庫實現可以優化存儲,以便每個值存儲在一個位中。

我如何確保使用vector<bool>確實存儲了向量中的位而不是布爾值(字節)?

不要試圖這樣做。 相反,使用boost::dynamic_bitset清楚地表明你真正想要的東西。 vector<bool>優化實際上為bug創建了許多可能性,例如在使用迭代器時(因為它通常返回一個代理對象)。

好吧,您可以隨時查看編譯器附帶的頭文件。 由於STL容器幾乎都是模板類,因此大多數(如果不是)實現的所有部分都將在標題中可見。

也許在調試器中查看vector對象也會有所幫助。

注意:你也應該知道vector<bool>同時被C ++社區所厭惡,而且這種優化是針對大小而不是速度:

https://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98

通過檢查vector<bool>::operator[]的非const版本的返回類型,可以在編譯時檢查它:將其值存儲為位的實現必須返回代理引用類而不是比一個bool&

這里根本沒有什么可以檢查的。 標准需要vector<bool>專門化來存儲位而不是更大的對象。 §23.2.5:“為了優化空間分配,提供了bool元素向量的特化:”。

我想從某種觀點來看,你引用的內容至少是正確的。 由於基本上沒有人可以證明編譯器的一致性,並且基本上沒有編譯器甚至嘗試滿足所有一致性要求,因此編譯器也可以選擇忽略此要求。

我不知道有任何編譯器這樣做 - 如果有人這樣做,我猜它可能是眾所周知的。 關於刪除vector<bool>專業化的討論有時會非常熱烈,所以如果有人有現實生活中有關做出更好(或更糟)的例子,我懷疑我們已經聽說過它了。

編輯:在C ++ 11中, std::vector<bool>要求已移至§23.3.7。 更重要的是,措辭已被更改,以指定將每個bool存儲為單個位而不是連續分配bool值的打包表示現在僅是建議。

至少IMO,這沒有什么真正的區別。 據我所知,所有實際的實現仍然使用打包表示,所以即使打包存儲不再在理論上得到保證,但無論如何它都會在實踐中發生。

這個程序可以證明它。

#include <vector>
#include <iostream>

template <typename T>
void showSize() {
    std::vector<T> myvec;
    size_t capacity = myvec.capacity();
    std::cout << "capacity: " << myvec.capacity() << std::endl;
    std::cout << "size: " << myvec.size() << std::endl;
    while (myvec.capacity() < 1024) {
        while (myvec.capacity() == capacity) {
            myvec.push_back(T());
        }
        capacity = myvec.capacity();
        std::cout << "capacity: " << myvec.capacity() << std::endl;
        std::cout << "size: " << myvec.size() << std::endl;
    }

}

int main(int, char**) {
    std::cout << std::endl << std::endl;
    std::cout << "*********************" << std::endl << std::endl;
    std::cout << "Booleans: " << std::endl << std::endl;
    showSize<bool>();
    std::cout << std::endl << std::endl;
    std::cout << "*********************" << std::endl << std::endl;
    std::cout << "Chars: " << std::endl << std::endl;
    showSize<char>();
}

輸出:

*********************

Booleans: 

capacity: 0
size: 0
capacity: 64
size: 1
capacity: 128
size: 65
capacity: 256
size: 129
capacity: 512
size: 257
capacity: 1024
size: 513


*********************

Chars: 

capacity: 0
size: 0
capacity: 1
size: 1
capacity: 2
size: 2
capacity: 4
size: 3
capacity: 8
size: 5
capacity: 16
size: 9
capacity: 32
size: 17
capacity: 64
size: 33
capacity: 128
size: 65
capacity: 256
size: 129
capacity: 512
size: 257
capacity: 1024
size: 513

所以關鍵是bool的容量一次增加64個條目(int或我的機器的大小)。 這暗示它一次只保留8個字節。

創建一個巨大的vector<bool>並查看程序的內存使用情況。

或者只是查看源代碼 - 您可以查看vector標題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM