保留STD向量的容量 模板专业化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了保留STD向量的容量 模板专业化相关的知识,希望对你有一定的参考价值。

我正在寻找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. 不保证同一容器中的不同元素可以由不同的线程同时修改。

然而,我没有看到这些措施如何能够产生我遇到的行为。

答案

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

您只看到std::vector<bool>发生这种情况的事实表明这是由于元素在内部存储的方式。

正如您已经了解到的那样,std::vector<bool>通常专门用于通过将元素打包成更大的类型来空间有效地将其元素存储为位。

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

以上是关于保留STD向量的容量 模板专业化的主要内容,如果未能解决你的问题,请参考以下文章

C++ STD 容器:std::vector - 有没有办法清除向量并保留存储分配?

容量是不是复制到向量中?

C++ 向量初始容量

C++初始化模板类

C++,2D std::vector,我是不是需要明确保留和推回空向量?

C ++模板专业化优先级。模板化专业化