Effective STL 学习笔记 Item 18: 慎用 vector<bool>
vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> 的注释中写的很清楚:
/** * @brief A specialization of vector for booleans which offers fixed time * access to individual elements in any order. * * Note that vector<bool> does not actually meet the requirements for being * a container. This is because the reference and pointer types are not * really references and pointers to bool. See DR96 for details. @see * vector for function documentation. * * @ingroup Containers * @ingroup Sequences * * In some terminology a %vector can be described as a dynamic * C-style array, it offers fast and efficient access to individual * elements in any order and saves the user from worrying about * memory and size allocation. Subscripting ( @c [ ] ) access is * also provided as with C-style arrays. */ template<typename _Alloc> class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> { // XXX: real declaration. }
C++ 标准中对容器的要求中有一条:
如果 c 是支持 [ ] 操作的 T 类型的容器,那么下面的表达式必须可以编译:
\(T* p = \&c[0]\)
但同样是按照 C++ 标准, vector<bool> 作为一个单独的对象,它里面存放的并非真正的 bool, 为了节省内存,其中存放的是 bitfields ,它用其中的每一个 bit 来表示 bool 。 不同于普通的 [ ] 操作符, vector<bool>::[ ] 返回并不是 bool& ,而是一个可以将 vector<bool> 的内部表示转换成 bool 类型的 proxy ,所以表达式:
vector<bool> c; bool* p = &c[0];
不能编译。
所以,用到 vector<bool> 的时候,切记它并非真正的容器,如果想用真正的存放 bool 类型的容器,需使用 deque 。
(使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)