如何检查vector <bool>是否实际上是位向量而不是字节?</bool>

时间:2013-01-14 21:12:44

标签: c++ stl vector boolean bits

我需要存储一个动态的位数组 The C++ reference page on vector< bool >具有以下信息:

  

存储不一定是bool值的数组,但库实现可以优化存储,以便将每个值存储在一个位中。

如何确保使用vector<bool>的程序确实存储了向量中的位而不是布尔值(字节)?

6 个答案:

答案 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标题。