Range-for-loops和std :: vector <bool>

时间:2015-12-04 01:25:30

标签: c++ c++11 for-loop range auto

为什么此代码有效

std::vector<int> intVector(10);
for(auto& i : intVector)
    std::cout << i;

这不是吗?

std::vector<bool> boolVector(10);
for(auto& i : boolVector)
    std::cout << i;

在后一种情况下,我收到错误

  

错误:从类型'std :: _ Bit_iterator :: reference {aka std :: _ Bit_reference}'的右值开始,无效初始化'std :: _ Bit_reference&amp;'类型的非const引用

for(auto& i : boolVector)

3 个答案:

答案 0 :(得分:26)

因为std::vector<bool> is not a container

std::vector<T>的迭代器通常取消引用T&,您可以绑定到自己的auto&

但是,

std::vector<bool>将其bool打包在整数内部,因此在访问它们时需要一个代理来执行位屏蔽。因此,它的迭代器返回Proxy 由于返回的Proxy是一个prvalue(一个临时的),它不能绑定到左值引用,例如auto&

解决方案:使用auto&&,如果给定一个,将正确折叠为左值引用,或者如果给定代理,则绑定并维护临时值。

答案 1 :(得分:8)

std::vector<bool>不符合标准容器规则。

特别是,其operator[]不会返回bool&

无效代码中的循环

#include <vector>
#include <iostream>

int main() {
  std::vector<bool> boolVector(10);
  for (auto& i: boolVector)
      std::cout << i;
}

可以用三种方式重写,以迭代值:

  1. (只读)

    for (auto i: boolVector)
        std::cout << i;
    
  2. (只读,可能效率低下)

    for (auto const& i: boolVector)  
        std::cout << i;
    
  3. (读/写)

    for (auto&& i: boolVector)
        std::cout << i;
    
  4. 第一个和最后一个之间的选择取决于您是需要修改向量中的值,还是只是为了读取它们。

答案 2 :(得分:6)

vector<bool> is (usually) specialized explicitly to store each bool in a single bit,将存储成本从每个值一个字节减少到每八个值一个字节。我所知道的处理器没有位可寻址,因此无法存储对vector<bool>中值的引用。您需要使用普通auto,而不是auto&作为迭代值i