我需要存储一个动态的位数组。
vector<bool> 上的 C++ 参考页有以下信息:
存储不一定是
bool
值数组,但库实现可以优化存储,以便每个值都存储在单个位中。
如何确保我使用的程序vector<bool>
确实将位存储在向量而不是布尔值(字节)中?
不要试图那样做。相反,使用boost::dynamic_bitset
which 清楚地表明你真正想要什么。优化实际上为错误创造了许多可能性,vector<bool>
例如在使用迭代器时(因为它通常返回一个代理对象)。
好吧,您总是可以查看编译器附带的头文件。由于 STL 容器几乎完全是模板类,因此实现的大部分(如果不是全部)部分将在标题中可见。
也许在调试器中查看vector
对象也会有所帮助。
注意:您还应该知道,vector<bool>
与此同时,C++ 社区对此颇为不满,并且这种优化是针对大小而不是速度的:
https://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98
这里根本没有什么可以检查的。标准要求专门vector<bool>
存储位而不是更大的对象。§23.2.5:“为了优化空间分配,提供了一个专门用于 bool 元素的向量:”。
我想从某种角度来看,您所引用的内容至少是正确的。由于基本上没有人可以证明编译器的一致性,而且基本上没有编译器甚至尝试满足所有一致性要求,因此编译器也可以选择忽略此要求。
不过,我不知道有任何编译器这样做——如果有人这样做,我猜它可能是众所周知的。有时关于取消vector<bool>
专业化的讨论非常激烈,所以如果有人有现实生活中的例子说明这让事情变得更好(或更糟),我怀疑我们会听说过它。
编辑:在 C++11 中,要求std::vector<bool>
已移至 §23.3.7。更重要的是,措辞已更改,以指定将每个bool
都存储为单个位而不是bool
值的连续分配的打包表示现在只是一个建议。
至少在国际海事组织,这几乎没有什么真正的区别。据我所知,所有实际实现仍然使用打包表示,因此即使打包存储在理论上不再得到保证,但无论如何它都会在实践中发生。
可以在编译时通过检查 的非常量版本的返回类型来检查这一点vector<bool>::operator[]
: 将其值存储为位的实现将必须返回代理引用类而不是bool&
.
这个程序证明了这一点。
#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
标题。