vectorbool 這麼多規則的異常
標準(第 23.3.7 節)規定提供 vector<bool>
的特化,它通過打包 bool
值來優化空間,因此每個僅佔用一位。由於在 C++中不能對位進行定址,這意味著對 vector
的幾個要求沒有放在 vector<bool>
上:
- 儲存的資料不需要是連續的,因此
vector<bool>
不能傳遞給期望bool
陣列的 C API。 at()
,operator []
和迭代器的解引用不會返回對bool
的引用。相反,他們通過過載其賦值運算子返回一個代理物件(不完美地)模擬對bool
的引用。例如,以下程式碼可能對std::vector<bool>
無效,因為解除引用迭代器不會返回引用:
Version >= C++ 11
std::vector<bool> v = {true, false};
for (auto &b: v) { } // error
類似地,期望 bool&
引數的函式不能與 operator []
或 at()
應用於 vector<bool>
的結果一起使用,或者使用解除引用其迭代器的結果:
void f(bool& b);
f(v[0]); // error
f(*v.begin()); // error
std::vector<bool>
的實現取決於編譯器和體系結構。通過將 n
布林值打包到記憶體的最低可定址部分來實現專業化。這裡,n
是最低可定址儲存器的位大小。在大多數現代系統中,這是 1 位元組或 8 位。這意味著一個位元組可以儲存 8 個布林值。這是對傳統實現的改進,其中 1 個布林值儲存在 1 位元組的儲存器中。
注意: 下面的示例顯示了傳統與優化的 vector<bool>
中單個位元組的可能按位值。這並不總是適用於所有架構。然而,它是視覺化優化的好方法。在下面的例子中,一個位元組表示為[x,x,x,x,x,x,x,x]。
傳統的 std::vector<char>
儲存 8 個布林值:
Version >= C++ 11
std::vector<char> trad_vect = {true, false, false, false, true, false, true, true};
按位表示:
[0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,1]
專門的 std::vector<bool>
儲存 8 個布林值:
Version >= C++ 11
std::vector<bool> optimized_vect = {true, false, false, false, true, false, true, true};
按位表示:
[1,0,0,0,1,0,1,1]
請注意,在上面的示例中,在傳統版本的 std::vector<bool>
中,8 個布林值佔用 8 個位元組的記憶體,而在優化版本的 std::vector<bool>
中,它們僅使用 1 個位元組的記憶體。這是對記憶體使用的重大改進。如果你需要將 vector<bool>
傳遞給 C 風格的 API,則可能需要將值複製到陣列中,或者如果記憶體和效能存在風險,則可以找到更好的方法來使用 API。