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