C++ 向量:那么多的例外,那么多的规则

示例

标准(第23.3.7节)规定提供的一种特殊化,vector<bool>通过打包bool值来优化空间,以便每个值仅占用一位。由于位不是寻址在C ++中,这意味着几个要求上vector未放置在vector<bool>:

  • 存储的数据不需要是连续的,因此vector<bool>不能将其传递给需要bool数组的C API 。

  • at(),operator []和迭代器的取消引用不会返回对的引用bool。相反,它们返回一个代理对象,该对象bool通过重载其赋值运算符来(不完美地)模拟对a的引用。例如,以下代码可能对无效std::vector<bool>,因为取消对迭代器的引用不会返回引用:

C ++ 11
std::vector<bool> v = {true, false};
for (auto &b: v) { } // 错误

同样,期望bool&参数的函数不能与的结果一起使用operator []或at()应用于vector<bool>,也不能与取消引用其迭代器的结果一起使用:

  void f(bool& b);
  f(v[0]);             // 错误
  f(*v.begin());       // 错误

的实现std::vector<bool>取决于编译器和体系结构。通过将n布尔值打包到内存的最低可寻址部分中来实现专业化。此处n是最低可寻址存储器的位大小。在大多数现代系统中,这是1字节或8位。这意味着一个字节可以存储8个布尔值。这是对传统实现的改进,在传统实现中,将1布尔值存储在1字节的内存中。

注意:以下示例显示了传统vs.优化中单个字节的可能按位值vector<bool>。并非在所有架构中都如此。但是,这是可视化优化的一种好方法。在下面的示例中,字节表示为[x,x,x,x,x,x,x,x]。

传统 std::vector<char>存储8个布尔值:

C ++ 11
std::vector<char> trad_vect = {true, false, false, false, true, false, true, true};

按位表示:

[0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,1], [0,0,0,0,0,0,0,1]

专门 std::vector<bool>存储8个布尔值:

C ++ 11
std::vector<bool> optimized_vect = {true, false, false, false, true, false, true, true};

按位表示:

[1,0,0,0,1,0,1,1]

请注意,在上述示例中,在传统版本的中std::vector<bool>,8个布尔值占用8个字节的内存,而在优化版本中std::vector<bool>,它们仅使用1字节的内存。这是内存使用方面的重大改进。如果您需要将A传递vector<bool>给C风格的API,则在内存和性能受到威胁的情况下,可能需要将值复制到数组中,或者找到使用API的更好方法。