代码之家  ›  专栏  ›  技术社区  ›  Eduardo J. Sanchez

为std vector<bool>模板专门化预留容量

  •  3
  • Eduardo J. Sanchez  · 技术社区  · 8 年前

    我正在研究 std::vector 对于类型 bool std::vector<bool> 。以下MWE创建一个对象并为其保留内存:

    #include <iostream>
    #include <vector>
    
    int main() {
      size_t nn{10};
      std::vector<bool> theVector{};
      theVector.reserve(nn);
    }
    

    但是,当我用以下方法编译这个mwe时:

    $ g++ --version
    g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
    

    通过这样做:

    $ g++ -std=c++14 -g mwe.cpp -o mwe
    

    然后使用以下方法进行调试:

    $ gdb --version
    GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
    

    我得到以下输出:

    Breakpoint 1, main () at mwe.cpp:6
    6     size_t nn{10};
    (gdb) n
    7     std::vector<bool> theVector{};
    (gdb) n
    8     theVector.reserve(nn);
    (gdb) p theVector 
    $1 = std::vector<bool> of length 0, capacity 0
    (gdb) n
    7     std::vector<bool> theVector{};
    (gdb) p theVector 
    $2 = std::vector<bool> of length 0, capacity 64
    (gdb) 
    

    当我指定总容量为10时,为什么我的容量为64?

    以前的研究让我了解了这个模板专门化。我从中学到了 cppreference.com 为了提高效率,此模板可以: 为了节省空间,它:

    1. 不一定将其元素存储为连续数组(因此 &v[0] + n != &v[n] )
    2. 公开类 std::vector<bool>::reference 作为访问单个位的方法。特别是,此类的对象由 operator[] 按值。
    3. 不使用 std::allocator_traits::construct 构造位值。
    4. 不能保证同一容器中的不同元素可以被不同的线程同时修改。

    然而,我不明白这些措施如何产生我所遇到的行为。

    1 回复  |  直到 8 年前
        1
  •  3
  •   Baum mit Augen    8 年前

    正如评论中已经指出的,如果发现合适的话,允许实现过度分配。

    你只看到这一切发生的原因 std::vector<bool> 建议这是由于元素在内部的存储方式。

    你已经知道了, STD::矢量& BoOL & GT; 通常专用于空间,通过将元素打包成更大的类型,有效地将其存储为位。

    因此,实际容量始终是可以存储在较大类型中的位数的倍数。在这种情况下,所说的类型似乎是64位宽,可能是一些无符号的64位整数。